Move Asterisk-addons modules into the main Asterisk source tree.
[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 "ooCapability.h"
17 #include "ootrace.h"
18 #include "ooCalls.h"
19 #include "ooh323ep.h"
20 #include "ooUtils.h"
21 /** Global endpoint structure */
22 extern OOH323EndPoint gH323ep;
23
24 static int giDynamicRTPPayloadType = 101;
25
26 int ooCapabilityEnableDTMFRFC2833
27    (OOH323CallData *call, int dynamicRTPPayloadType)
28 {
29    if(!call)
30    {
31       gH323ep.dtmfmode |= OO_CAP_DTMF_RFC2833;
32       OOTRACEINFO1("Enabled RFC2833 DTMF capability for end-point\n");
33    }
34    else{
35       call->dtmfmode |= OO_CAP_DTMF_RFC2833;
36       OOTRACEINFO3("Enabled RFC2833 DTMF capability for (%s, %s) \n", 
37                    call->callType, call->callToken);
38    }
39
40    /*Dynamic RTP payload type range is from 96 - 127 */
41    if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127)
42       giDynamicRTPPayloadType = dynamicRTPPayloadType;
43
44    return OO_OK;
45 }
46
47
48
49 int ooCapabilityDisableDTMFRFC2833(OOH323CallData *call)
50 {
51    if(!call){
52       gH323ep.dtmfmode ^= OO_CAP_DTMF_RFC2833;
53       OOTRACEINFO1("Disabled RFC2833 DTMF capability for end-point\n");
54    }
55    else{
56       call->dtmfmode ^= OO_CAP_DTMF_RFC2833;
57       OOTRACEINFO3("Disabled RFC2833 DTMF capability for (%s, %s)\n", 
58                     call->callType, call->callToken);
59    }
60
61    return OO_OK;
62 }
63
64 int ooCapabilityEnableDTMFH245Alphanumeric(OOH323CallData *call)
65 {
66    if(!call){
67       gH323ep.dtmfmode |= OO_CAP_DTMF_H245_alphanumeric;
68       OOTRACEINFO1("Dtmf mode set to H.245(alphanumeric) for endpoint\n");
69    }
70    else {
71       call->dtmfmode |= OO_CAP_DTMF_H245_alphanumeric;
72       OOTRACEINFO3("Dtmf mode set to H.245(alphanumeric) for (%s, %s)\n", 
73                     call->callType, call->callToken);
74    }
75    return OO_OK;
76 }
77
78 int ooCapabilityDisableDTMFH245Alphanumeric(OOH323CallData *call)
79 {
80    if(!call){
81       gH323ep.dtmfmode ^= OO_CAP_DTMF_H245_alphanumeric;
82       OOTRACEINFO1("Dtmf mode H.245(alphanumeric) disabled for endpoint\n");
83    }
84    else {
85       call->dtmfmode ^= OO_CAP_DTMF_H245_alphanumeric;
86       OOTRACEINFO3("Dtmf mode H.245(alphanumeric) disabled for (%s, %s)\n", 
87                     call->callType, call->callToken);
88    }
89    return OO_OK;
90 }
91
92 int ooCapabilityEnableDTMFH245Signal(OOH323CallData *call)
93 {
94    if(!call){
95       gH323ep.dtmfmode |= OO_CAP_DTMF_H245_signal;
96       OOTRACEINFO1("Dtmf mode set to H.245(signal) for endpoint\n");
97    }
98    else {
99       call->dtmfmode |= OO_CAP_DTMF_H245_signal;
100       OOTRACEINFO3("Dtmf mode set to H.245(signal) for (%s, %s)\n", 
101                     call->callType, call->callToken);
102    }
103    return OO_OK;
104 }
105
106 int ooCapabilityDisableDTMFH245Signal(OOH323CallData *call)
107 {
108    if(!call){
109       gH323ep.dtmfmode ^= OO_CAP_DTMF_H245_signal;
110       OOTRACEINFO1("Dtmf mode H.245(signal) disabled for endpoint\n");
111    }
112    else {
113       call->dtmfmode ^= OO_CAP_DTMF_H245_signal;
114       OOTRACEINFO3("Dtmf mode H.245(signal) disabled for (%s, %s)\n", 
115                     call->callType, call->callToken);
116    }
117    return OO_OK;
118 }
119
120 int ooCapabilityEnableDTMFQ931Keypad(struct OOH323CallData *call)
121 {
122    if(!call){
123       gH323ep.dtmfmode |= OO_CAP_DTMF_Q931;
124       OOTRACEINFO1("Dtmf mode set to Q.931(keypad) for the endpoint\n");
125    }
126    else {
127       call->dtmfmode |= OO_CAP_DTMF_Q931;
128       OOTRACEINFO3("Dtmf mode set to Q.931(keypad) for the call (%s, %s)\n", 
129                     call->callType, call->callToken);
130    }
131    return OO_OK;
132 }
133
134 int ooCapabilityDisableDTMFQ931Keypad(struct OOH323CallData *call)
135 {
136    if(!call){
137       gH323ep.dtmfmode ^= OO_CAP_DTMF_Q931;
138       OOTRACEINFO1("Dtmf mode Q.931(keypad) disabled for the endpoint\n");
139    }
140    else {
141       call->dtmfmode ^= OO_CAP_DTMF_Q931;
142       OOTRACEINFO3("Dtmf mode Q.931(keypad) disabled for the call (%s, %s)\n", 
143                     call->callType, call->callToken);
144    }
145    return OO_OK;
146 }
147
148 int ooCapabilityAddH263VideoCapability(ooCallData *call, 
149                               unsigned sqcifMPI, unsigned qcifMPI, 
150                               unsigned cifMPI, unsigned cif4MPI, 
151                               unsigned cif16MPI, unsigned maxBitRate, int dir, 
152                               cb_StartReceiveChannel startReceiveChannel,
153                               cb_StartTransmitChannel startTransmitChannel,
154                               cb_StopReceiveChannel stopReceiveChannel,
155                               cb_StopTransmitChannel stopTransmitChannel, 
156                               OOBOOL remote)
157 {
158    int ret = OO_OK;
159    if(sqcifMPI>0)
160    {
161       ret = ooCapabilityAddH263VideoCapability_helper(call, sqcifMPI, 0, 
162                                  0, 0, 0, maxBitRate, dir, startReceiveChannel,
163                                  startTransmitChannel, stopReceiveChannel,
164                                  stopTransmitChannel, remote);
165       if(ret != OO_OK)
166       {
167          OOTRACEERR1("Error: Failed to add H263 sqcifMPI capability\n");
168          return OO_FAILED;
169       }
170    }
171    if(qcifMPI>0)
172    {
173       ret = ooCapabilityAddH263VideoCapability_helper(call, 0, qcifMPI, 0,
174                                  0, 0, maxBitRate, dir, startReceiveChannel,
175                                  startTransmitChannel, stopReceiveChannel,
176                                  stopTransmitChannel, remote);
177       if(ret != OO_OK)
178       {
179          OOTRACEERR1("Error: Failed to add H263 qcifMPI capability\n");
180          return OO_FAILED;
181       }
182    }
183    if(cifMPI>0)
184    {
185       ret = ooCapabilityAddH263VideoCapability_helper(call, 0, 0, cifMPI, 
186                                  0, 0, maxBitRate, dir, startReceiveChannel,
187                                  startTransmitChannel, stopReceiveChannel,
188                                  stopTransmitChannel, remote);
189       if(ret != OO_OK)
190       {
191          OOTRACEERR1("Error: Failed to add H263 cifMPI capability\n");
192          return OO_FAILED;
193       }
194    }
195    if(cif4MPI>0)
196    {
197       ret = ooCapabilityAddH263VideoCapability_helper(call, 0, 0, 0, 
198                                  cif4MPI, 0, maxBitRate, dir, 
199                                  startReceiveChannel,
200                                  startTransmitChannel, stopReceiveChannel,
201                                  stopTransmitChannel, remote);
202       if(ret != OO_OK)
203       {
204          OOTRACEERR1("Error: Failed to add H263 cif4MPI capability\n");
205          return OO_FAILED;
206       }
207    }
208    if(cif16MPI>0)
209    {
210       ret = ooCapabilityAddH263VideoCapability_helper(call, dir, 0, 0, 0, 0, 
211                                  cif16MPI, maxBitRate, startReceiveChannel,
212                                  startTransmitChannel, stopReceiveChannel,
213                                  stopTransmitChannel, remote);
214       if(ret != OO_OK)
215       {
216          OOTRACEERR1("Error: Failed to add H263 cif16MPI capability\n");
217          return OO_FAILED;
218       }
219    }
220    return OO_OK;
221
222 }
223
224 int ooCapabilityAddH263VideoCapability_helper(ooCallData *call,
225                               unsigned sqcifMPI, unsigned qcifMPI, 
226                               unsigned cifMPI, unsigned cif4MPI, 
227                               unsigned cif16MPI, unsigned maxBitRate, int dir, 
228                               cb_StartReceiveChannel startReceiveChannel,
229                               cb_StartTransmitChannel startTransmitChannel,
230                               cb_StopReceiveChannel stopReceiveChannel,
231                               cb_StopTransmitChannel stopTransmitChannel, 
232                               OOBOOL remote)
233 {
234
235    ooH323EpCapability *epCap = NULL, *cur=NULL;
236    OOH263CapParams *params=NULL;   
237    OOCTXT *pctxt=NULL;
238    char *pictureType = NULL;
239    int cap = OO_H263VIDEO;
240
241    if(!call) pctxt = &gH323ep.ctxt;
242    else pctxt = call->pctxt;
243
244    epCap = (ooH323EpCapability*)memAllocZ(pctxt, sizeof(ooH323EpCapability));
245    params = (OOH263CapParams*) memAllocZ(pctxt, sizeof(OOH263CapParams));
246    if(!epCap || !params)
247    {
248       OOTRACEERR1("Error:Memory - ooCapabilityAddH263Capability - epCap/params"
249                   ".\n");
250       return OO_FAILED;
251    }
252    
253    if(sqcifMPI>0)
254    {
255       params->MPI = sqcifMPI;
256       params->picFormat = OO_PICFORMAT_SQCIF;
257       pictureType = "SQCIF";
258    }
259    if(qcifMPI>0)
260    {
261       params->MPI = qcifMPI;
262       params->picFormat =  OO_PICFORMAT_QCIF;
263       pictureType = "QCIF";
264    }
265    if(cifMPI>0)
266    {
267       params->MPI = cifMPI;
268       params->picFormat = OO_PICFORMAT_CIF;
269       pictureType = "CIF";
270    }
271    if(cif4MPI>0)
272    {
273       params->MPI = cif4MPI;
274       params->picFormat = OO_PICFORMAT_CIF4;
275       pictureType = "CIF4";
276    }
277    if(cif16MPI>0)
278    {
279       params->MPI = cif16MPI;
280       params->picFormat = OO_PICFORMAT_CIF16;
281       pictureType = "CIF16";
282    }
283
284    params->maxBitRate = maxBitRate;
285
286
287    if(dir & OORXANDTX)
288    {
289       epCap->dir = OORX;
290       epCap->dir |= OOTX;
291    }
292    else
293       epCap->dir = dir;
294    
295    epCap->cap = OO_H263VIDEO;
296    epCap->capType = OO_CAP_TYPE_VIDEO;
297    epCap->params = (void*)params;
298    epCap->startReceiveChannel = startReceiveChannel;
299    epCap->startTransmitChannel = startTransmitChannel;
300    epCap->stopReceiveChannel = stopReceiveChannel;
301    epCap->stopTransmitChannel = stopTransmitChannel;
302    
303    epCap->next = NULL;
304
305    if(!call)
306    {/*Add as local capability */
307       OOTRACEDBGC2("Adding endpoint H263 video capability %s.\n", pictureType);
308       if(!gH323ep.myCaps)
309          gH323ep.myCaps = epCap;
310       else{
311          cur = gH323ep.myCaps;
312          while(cur->next) cur = cur->next;
313          cur->next = epCap;
314       }
315       ooAppendCapToCapPrefs(NULL, cap);
316       gH323ep.noOfCaps++;
317    }
318    else{
319       if(remote)
320       {
321          /*Add as remote capability */
322          if(!call->remoteCaps)
323             call->remoteCaps = epCap;
324          else{
325             cur = call->remoteCaps;
326             while(cur->next) cur = cur->next;
327             cur->next = epCap;
328          }
329      }
330      else{
331         /*Add as our capability */
332         OOTRACEDBGC4("Adding call specific H263 video capability %s. "
333                      "(%s, %s)\n", pictureType, call->callType, 
334                      call->callToken);
335         if(!call->ourCaps){
336            call->ourCaps = epCap;
337            ooResetCapPrefs(call);
338         }
339         else{
340            cur = call->ourCaps;
341            while(cur->next) cur = cur->next;
342            cur->next = epCap;
343         }
344         ooAppendCapToCapPrefs(call, cap);
345      }
346    }
347
348    return OO_OK;
349 }
350
351 /* Used for g711 ulaw/alaw, g728, g729 and g7231 */
352 int ooCapabilityAddSimpleCapability
353    (OOH323CallData *call, int cap, int txframes, 
354     int rxframes, OOBOOL silenceSuppression, int dir, 
355     cb_StartReceiveChannel startReceiveChannel,
356     cb_StartTransmitChannel startTransmitChannel,
357     cb_StopReceiveChannel stopReceiveChannel,
358     cb_StopTransmitChannel stopTransmitChannel,
359     OOBOOL remote)
360 {
361    ooH323EpCapability *epCap = NULL, *cur=NULL;
362    OOCapParams *params=NULL;   
363    OOCTXT *pctxt=NULL;
364    if(!call) pctxt = &gH323ep.ctxt;
365    else pctxt = call->pctxt;
366
367    epCap = (ooH323EpCapability*)memAlloc(pctxt, sizeof(ooH323EpCapability));
368    params = (OOCapParams*) memAlloc(pctxt, sizeof(OOCapParams));
369    if(!epCap || !params)
370    {
371       OOTRACEERR1("ERROR: Memory - ooCapabilityAddSimpleCapability - "
372                   "epCap/params\n");
373       return OO_FAILED;
374    }
375
376
377    params->txframes = txframes;
378    params->rxframes = rxframes;
379    /* Ignore silence suppression parameter unless cap is g7231 */
380    if(cap == OO_G7231)
381       params->silenceSuppression = silenceSuppression;
382    else
383       params->silenceSuppression = FALSE; /* Set to false for g711 and g729*/
384
385    if(dir & OORXANDTX) {
386       epCap->dir = OORX;
387       epCap->dir |= OOTX;
388    }
389    else {
390       epCap->dir = dir;
391    }
392    
393    epCap->cap = cap;
394    epCap->capType = OO_CAP_TYPE_AUDIO;
395    epCap->params = (void*)params;
396    epCap->startReceiveChannel = startReceiveChannel;
397    epCap->startTransmitChannel = startTransmitChannel;
398    epCap->stopReceiveChannel = stopReceiveChannel;
399    epCap->stopTransmitChannel = stopTransmitChannel;
400    epCap->next = NULL;
401
402    if(!call)
403    {
404       /* Add as local capability */
405       OOTRACEDBGC2("Adding endpoint capability %s. \n", 
406                      ooGetCapTypeText(epCap->cap));
407       if(!gH323ep.myCaps) {
408          gH323ep.myCaps = epCap;
409       }
410       else{
411          cur = gH323ep.myCaps;
412          while(cur->next) cur = cur->next;
413          cur->next = epCap;
414       }
415       ooAppendCapToCapPrefs(NULL, cap);
416       gH323ep.noOfCaps++;
417    }
418    else{
419       if(remote)
420       {
421          /* Add as remote capability */
422          if(!call->remoteCaps) {
423             call->remoteCaps = epCap;
424          }
425          else{
426             cur = call->remoteCaps;
427             while(cur->next) cur = cur->next;
428             cur->next = epCap;
429          }
430       }
431       else{
432          /* Add as our capability */
433          OOTRACEDBGC4("Adding call specific capability %s. (%s, %s)\n", 
434                       ooGetCapTypeText(epCap->cap), call->callType, 
435                       call->callToken);
436          if(!call->ourCaps){
437             call->ourCaps = epCap;
438             ooResetCapPrefs(call);
439          }
440          else{
441             cur = call->ourCaps;
442             while(cur->next) cur = cur->next;
443             cur->next = epCap;
444          }
445          ooAppendCapToCapPrefs(call, cap);
446       }
447    }
448            
449    return OO_OK;
450 }
451
452
453 int ooCapabilityAddGSMCapability(OOH323CallData *call, int cap, 
454                                 unsigned framesPerPkt, OOBOOL comfortNoise,
455                                 OOBOOL scrambled, int dir, 
456                                 cb_StartReceiveChannel startReceiveChannel,
457                                 cb_StartTransmitChannel startTransmitChannel,
458                                 cb_StopReceiveChannel stopReceiveChannel,
459                                 cb_StopTransmitChannel stopTransmitChannel, 
460                                 OOBOOL remote)
461 {
462
463    ooH323EpCapability *epCap = NULL, *cur=NULL;
464    OOGSMCapParams *params=NULL;   
465    OOCTXT *pctxt = NULL;
466  
467    if(!call) pctxt = &gH323ep.ctxt;
468    else pctxt = call->pctxt;
469
470    epCap = (ooH323EpCapability*)memAlloc(pctxt, sizeof(ooH323EpCapability));
471    params = (OOGSMCapParams*) memAlloc(pctxt, sizeof(OOGSMCapParams));
472    if(!epCap || !params)
473    {
474       OOTRACEERR1("Error:Memory - ooCapabilityAddGSMCapability - "
475                   "epCap/params\n");
476       return OO_FAILED;
477    }
478
479
480    params->rxframes = framesPerPkt;
481    params->txframes = framesPerPkt;
482    params->comfortNoise = comfortNoise;
483    params->scrambled = scrambled;
484    if(dir & OORXANDTX)
485    {
486       epCap->dir = OORX;
487       epCap->dir |= OOTX;
488    }
489    else
490       epCap->dir = dir;
491
492    epCap->cap = cap;
493    epCap->capType = OO_CAP_TYPE_AUDIO;
494    epCap->params = (void*)params;
495    epCap->startReceiveChannel = startReceiveChannel;
496    epCap->startTransmitChannel = startTransmitChannel;
497    epCap->stopReceiveChannel = stopReceiveChannel;
498    epCap->stopTransmitChannel = stopTransmitChannel;
499    
500    epCap->next = NULL;
501    /* Add as local capability */
502    if(!call)
503    {
504       if(!gH323ep.myCaps)
505          gH323ep.myCaps = epCap;
506       else{
507          cur = gH323ep.myCaps;
508          while(cur->next) cur = cur->next;
509          cur->next = epCap;
510       }
511       ooAppendCapToCapPrefs(NULL, cap);
512       gH323ep.noOfCaps++;
513    }
514    else{
515       if(remote)
516       {
517          /*Add as remote capability */
518          if(!call->remoteCaps)
519             call->remoteCaps = epCap;
520          else{
521             cur = call->remoteCaps;
522             while(cur->next) cur = cur->next;
523             cur->next = epCap;
524          }
525       }
526       else{
527          OOTRACEDBGC4("Adding call specific capability %s. (%s, %s)\n", 
528                      ooGetCapTypeText(epCap->cap), call->callType, 
529                      call->callToken);
530          /*Add as our capability */
531          if(!call->ourCaps){
532             call->ourCaps = epCap;
533             ooResetCapPrefs(call);
534          }
535          else{
536             cur = call->ourCaps;
537             while(cur->next) cur = cur->next;
538             cur->next = epCap;
539          }
540          ooAppendCapToCapPrefs(call, cap);
541       }
542    }
543
544    return OO_OK;
545 }
546
547
548
549
550 struct H245VideoCapability* ooCapabilityCreateVideoCapability
551       (ooH323EpCapability *epCap, OOCTXT *pctxt, int dir)
552 {
553
554    if(!epCap)
555    {
556      OOTRACEERR1("Error:Invalid capability parameter passed to "
557                  "ooCapabilityCreateVideoCapability.\n");
558      return NULL;
559    }
560    
561    if(!(epCap->dir & dir))
562    {
563       OOTRACEERR1("Error:Failed to create capability due to direction "
564                   "mismatch.\n");
565       return NULL;
566    }
567
568    switch(epCap->cap)
569    {
570    case OO_H263VIDEO:
571      return ooCapabilityCreateH263VideoCapability(epCap, pctxt, dir);
572
573    case OO_NONSTDVIDEO:
574    case OO_H261VIDEO:
575    case OO_H262VIDEO:
576    case OO_IS11172VIDEO:
577    case OO_GENERICVIDEO:
578    case OO_EXTELEMVIDEO:
579    default:
580       OOTRACEERR2("ERROR: Don't know how to create video capability %s\n",
581                   ooGetCapTypeText(epCap->cap));
582    }
583    return NULL;
584 }
585
586
587    
588 struct H245AudioCapability* ooCapabilityCreateAudioCapability
589       (ooH323EpCapability *epCap, OOCTXT *pctxt, int dir)
590 {
591
592    if(!epCap)
593    {
594      OOTRACEERR1("Error:Invalid capability parameter passed to "
595                  "ooCapabilityCreateAudioCapability.\n");
596      return NULL;
597    }
598    
599    if(!(epCap->dir & dir))
600    {
601       OOTRACEERR1("Error:Failed to create capability due to direction "
602                   "mismatch.\n");
603       return NULL;
604    }
605
606    switch(epCap->cap)
607    {
608    case OO_G711ALAW64K:
609    case OO_G711ALAW56K:
610    case OO_G711ULAW64K:
611    case OO_G711ULAW56K:
612    /*case OO_G726:*/
613    case OO_G728:
614    case OO_G729:
615    case OO_G729A:
616    case OO_G7231:
617      return ooCapabilityCreateSimpleCapability(epCap, pctxt, dir);
618    case OO_GSMFULLRATE:
619       return ooCapabilityCreateGSMFullRateCapability(epCap, pctxt, dir);
620    default:
621       OOTRACEERR2("ERROR: Don't know how to create audio capability %d\n",
622                   epCap->cap);
623    }
624    return NULL;
625 }
626
627
628
629 void* ooCapabilityCreateDTMFCapability(int cap, OOCTXT *pctxt)
630 {
631    H245AudioTelephonyEventCapability *pATECap=NULL;
632    H245UserInputCapability *userInput = NULL;
633    char *events=NULL;
634    switch(cap)
635    {
636    case OO_CAP_DTMF_RFC2833:
637       pATECap = (H245AudioTelephonyEventCapability*)memAlloc(pctxt, 
638                                    sizeof(H245AudioTelephonyEventCapability));
639       if(!pATECap)
640       {
641          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - pATECap\n");
642          return NULL;
643       }
644       memset(pATECap, 0, sizeof(H245AudioTelephonyEventCapability));
645       pATECap->dynamicRTPPayloadType = giDynamicRTPPayloadType;
646       events = (char*)memAlloc(pctxt, strlen("0-16")+1);
647       if(!events)
648       {
649          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - events\n");
650          memFreePtr(pctxt, pATECap);
651          return NULL;
652       }
653       strncpy(events, "0-16", strlen("0-16"));
654       pATECap->audioTelephoneEvent = events;
655       return pATECap;
656    case OO_CAP_DTMF_H245_alphanumeric:
657       userInput = (H245UserInputCapability*)memAllocZ(pctxt, 
658                                           sizeof(H245UserInputCapability));
659       if(!userInput)
660       {
661          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - "
662                      "userInput\n");
663          return NULL;
664       }
665       userInput->t = T_H245UserInputCapability_basicString;
666       return userInput;
667    case OO_CAP_DTMF_H245_signal:
668       userInput = (H245UserInputCapability*)memAllocZ(pctxt, 
669                                           sizeof(H245UserInputCapability));
670       if(!userInput)
671       {
672          OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - "
673                      "userInput\n");
674          return NULL;
675       }
676       userInput->t = T_H245UserInputCapability_dtmf;
677       return userInput;
678    default:
679      OOTRACEERR1("Error:unknown dtmf capability type\n");
680    }
681    return NULL;
682 }
683
684
685
686 struct H245VideoCapability* ooCapabilityCreateH263VideoCapability
687    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
688 {
689    H245VideoCapability *pVideo=NULL;
690    OOH263CapParams *params=NULL;
691    H245H263VideoCapability *pH263Cap=NULL;
692
693    if(!epCap || !epCap->params)
694    {
695      OOTRACEERR1("Error:Invalid capability parameters to "
696                  "ooCapabilityCreateH263VideoCapability.\n");
697      return NULL;
698    }
699    params =(OOH263CapParams*)epCap->params;
700
701    pVideo = (H245VideoCapability*)memAllocZ(pctxt, 
702                                                   sizeof(H245VideoCapability));
703    pH263Cap = (H245H263VideoCapability*) memAllocZ(pctxt, 
704                                              sizeof(H245H263VideoCapability));
705    if(!pVideo || !pH263Cap)
706    {
707       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateH263VideoCapability - "
708                   "pVideo/pH263Cap\n");
709       return NULL;
710    }
711
712    pVideo->t = T_H245VideoCapability_h263VideoCapability;
713    pVideo->u.h263VideoCapability = pH263Cap;
714
715
716    if(params->picFormat ==  OO_PICFORMAT_SQCIF) {
717       pH263Cap->m.sqcifMPIPresent = TRUE;
718       pH263Cap->sqcifMPI = params->MPI;
719    }
720    else if(params->picFormat == OO_PICFORMAT_QCIF) {
721       pH263Cap->m.qcifMPIPresent = TRUE;
722       pH263Cap->qcifMPI = params->MPI;
723    }
724    else if(params->picFormat == OO_PICFORMAT_CIF) {
725       pH263Cap->m.cifMPIPresent = TRUE;
726       pH263Cap->cifMPI = params->MPI;
727    }
728    else if(params->picFormat == OO_PICFORMAT_CIF4) {
729       pH263Cap->m.cif4MPIPresent  = TRUE;
730       pH263Cap->cif4MPI = params->MPI;
731    }
732    else if(params->picFormat == OO_PICFORMAT_CIF16) {
733       pH263Cap->m.cif16MPIPresent = TRUE;
734       pH263Cap->cif16MPI = params->MPI;
735    }
736
737    pH263Cap->m.errorCompensationPresent = TRUE;
738    pH263Cap->maxBitRate = params->maxBitRate;
739    pH263Cap->unrestrictedVector = FALSE;
740    pH263Cap->arithmeticCoding = FALSE;
741    pH263Cap->advancedPrediction = FALSE;
742    pH263Cap->pbFrames = FALSE;
743    pH263Cap->temporalSpatialTradeOffCapability = FALSE;
744    pH263Cap->hrd_B = 0;
745    pH263Cap->bppMaxKb = 0;
746    pH263Cap->slowSqcifMPI = FALSE;
747    pH263Cap->slowQcifMPI = FALSE;
748    pH263Cap->slowCifMPI = FALSE;
749    pH263Cap->slowCif4MPI = FALSE;
750    pH263Cap->slowCif16MPI = FALSE;
751    pH263Cap->errorCompensation = FALSE;
752    return pVideo;
753 }
754
755 struct H245AudioCapability* ooCapabilityCreateGSMFullRateCapability
756    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
757 {
758    H245AudioCapability *pAudio=NULL;
759    H245GSMAudioCapability *pGSMCap=NULL;
760    if(!epCap || !epCap->params)
761    {
762      OOTRACEERR1("Error:Invalid capability parameters to "
763                  "ooCapabilityCreateGSMFullRateCapability.\n");
764      return NULL;
765    }
766
767    pAudio = (H245AudioCapability*)memAlloc(pctxt, 
768                                                 sizeof(H245AudioCapability));
769    pGSMCap = (H245GSMAudioCapability*)memAlloc(pctxt, 
770                                               sizeof(H245GSMAudioCapability));
771    if(!pAudio || !pGSMCap)
772    {
773       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateGSMFullRateCapability - "
774                   "pAudio/pGSMCap\n");
775       return NULL;
776    }
777    
778    pAudio->t = T_H245AudioCapability_gsmFullRate;
779    pAudio->u.gsmFullRate = pGSMCap;
780    if(dir & OORX)
781       pGSMCap->audioUnitSize = ((OOGSMCapParams*)epCap->params)->rxframes*OO_GSMFRAMESIZE;
782    else
783       pGSMCap->audioUnitSize = ((OOGSMCapParams*)epCap->params)->txframes*OO_GSMFRAMESIZE;
784  
785    pGSMCap->comfortNoise = ((OOGSMCapParams*)epCap->params)->comfortNoise;
786    pGSMCap->scrambled = ((OOGSMCapParams*)epCap->params)->scrambled;
787
788    return pAudio;
789 }
790
791 /* This is used for g711 ulaw/alaw, g728, g729, g729A, g7231*/
792 struct H245AudioCapability* ooCapabilityCreateSimpleCapability
793    (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
794 {
795    H245AudioCapability *pAudio=NULL;
796    OOCapParams *params;
797    if(!epCap || !epCap->params)
798    {
799      OOTRACEERR1("Error:Invalid capability parameters to "
800                  "ooCapabilityCreateSimpleCapability.\n");
801      return NULL;
802    }
803    params =(OOCapParams*)epCap->params;
804    pAudio = (H245AudioCapability*)memAlloc(pctxt, 
805                                                 sizeof(H245AudioCapability));
806    if(!pAudio)
807    {
808       OOTRACEERR1("ERROR:Memory - ooCapabilityCreateSimpleCapability - pAudio\n");
809       return NULL;
810    }
811
812    
813    switch(epCap->cap)
814    {
815    case OO_G711ALAW64K:
816       pAudio->t = T_H245AudioCapability_g711Alaw64k;
817       if(dir & OORX)
818          pAudio->u.g711Alaw64k = params->rxframes;
819       else
820          pAudio->u.g711Alaw64k = params->txframes;
821       return pAudio;
822    case OO_G711ALAW56K:
823       pAudio->t = T_H245AudioCapability_g711Alaw56k;
824       if(dir & OORX)
825          pAudio->u.g711Alaw56k = params->rxframes;
826       else
827          pAudio->u.g711Alaw56k = params->txframes; 
828       return pAudio;
829    case OO_G711ULAW64K:
830       pAudio->t = T_H245AudioCapability_g711Ulaw64k;
831       if(dir & OORX)
832          pAudio->u.g711Ulaw64k = params->rxframes;
833       else
834          pAudio->u.g711Ulaw64k = params->txframes;
835       return pAudio;
836    case OO_G711ULAW56K:
837       pAudio->t = T_H245AudioCapability_g711Ulaw56k;
838       if(dir & OORX)
839          pAudio->u.g711Ulaw56k = params->rxframes;
840       else
841          pAudio->u.g711Ulaw64k = params->txframes;
842       return pAudio;
843    /*case OO_G726:
844       pAudio->t = T_H245AudioCapability_g726;
845       if(dir & OORX)
846          pAudio->u.g726 = params->rxframes;
847       else
848          pAudio->u.g726 = params->txframes;
849       return pAudio;*/
850    case OO_G728:
851       pAudio->t = T_H245AudioCapability_g728;
852       if(dir & OORX)
853          pAudio->u.g728 = params->rxframes;
854       else
855          pAudio->u.g728 = params->txframes;
856       return pAudio;
857    case OO_G729:
858       pAudio->t = T_H245AudioCapability_g729;
859       if(dir & OORX)
860          pAudio->u.g729 = params->rxframes;
861       else
862          pAudio->u.g729 = params->txframes;
863       return pAudio;
864    case OO_G729A:
865       pAudio->t = T_H245AudioCapability_g729AnnexA;
866       if(dir & OORX)
867          pAudio->u.g729AnnexA = params->rxframes;
868       else
869          pAudio->u.g729AnnexA = params->txframes;
870       return pAudio;
871    case OO_G7231:
872       pAudio->t = T_H245AudioCapability_g7231;
873       pAudio->u.g7231 = (H245AudioCapability_g7231*)memAlloc(pctxt, 
874                                            sizeof(H245AudioCapability_g7231));
875       if(!pAudio->u.g7231)
876       {
877          OOTRACEERR1("Error:Memory - ooCapabilityCreateSimpleCapability - g7231\n");
878          memFreePtr(pctxt, pAudio);
879          return NULL;
880       }
881       pAudio->u.g7231->silenceSuppression = params->silenceSuppression;
882       if(dir & OORX)
883          pAudio->u.g7231->maxAl_sduAudioFrames = params->rxframes;
884       else
885          pAudio->u.g7231->maxAl_sduAudioFrames = params->txframes;
886       return pAudio;
887
888    default:
889       OOTRACEERR2("ERROR: Don't know how to create audio capability %d\n",
890                    epCap->cap);
891    }
892    return NULL;
893 }
894
895 /* Used for g711 ulaw/alaw, g728, g729, g729a, g7231 */
896 ASN1BOOL ooCapabilityCheckCompatibility_Simple
897    (OOH323CallData *call, ooH323EpCapability* epCap, 
898     H245AudioCapability* audioCap, int dir)
899 {
900    int noofframes=0, cap;
901
902    OOTRACEDBGC2("Comparing channel with codec type: %d\n", audioCap->t);
903
904    switch(audioCap->t)
905    {
906    case T_H245AudioCapability_g711Ulaw56k:
907       cap = OO_G711ULAW56K;
908       noofframes = audioCap->u.g711Ulaw56k;
909       break;
910    case T_H245AudioCapability_g711Ulaw64k:
911       cap = OO_G711ULAW64K;
912       noofframes = audioCap->u.g711Ulaw64k;
913       break;
914    case T_H245AudioCapability_g711Alaw64k:
915       cap = OO_G711ALAW64K;
916       noofframes = audioCap->u.g711Alaw64k;
917       break;
918    case T_H245AudioCapability_g711Alaw56k:
919       cap = OO_G711ALAW56K;
920       noofframes = audioCap->u.g711Alaw56k;
921       break;
922    /*case T_H245AudioCapability_g726:
923       cap = OO_G726;
924       noofframes = audioCap->u.g726;
925       break;*/
926    case T_H245AudioCapability_g728:
927       cap = OO_G728;
928       noofframes = audioCap->u.g728;
929       break;
930    case T_H245AudioCapability_g729:
931       cap = OO_G729;
932       noofframes = audioCap->u.g729;
933       break;
934    case T_H245AudioCapability_g729AnnexA:
935       cap = OO_G729A;
936       noofframes = audioCap->u.g729AnnexA;
937       break;   
938    case T_H245AudioCapability_g7231:
939      cap = OO_G7231;
940      noofframes = audioCap->u.g7231->maxAl_sduAudioFrames;
941      break;
942    default:
943       return FALSE;
944    }
945
946    OOTRACEDBGC3("Comparing codecs: current=%d, requested=%d\n", 
947       epCap->cap, cap);
948    if(cap != epCap->cap) { return FALSE; }
949
950    /* Can we receive this capability */
951    if(dir & OORX)
952    {
953       OOTRACEDBGC3("Comparing RX frame rate: channel's=%d, requested=%d\n",
954          ((OOCapParams*)epCap->params)->rxframes, noofframes);
955       if(((OOCapParams*)epCap->params)->rxframes >= noofframes) {
956          return TRUE;
957       }
958       //else {
959       //  not supported, as already told other ep our max. receive rate
960       //  our ep can't receive more rate than it
961       //  return FALSE;
962       //}
963    }
964
965    /* Can we transmit compatible stream */
966    if(dir & OOTX)
967    {
968       OOTRACEDBGC3("Comparing TX frame rate: channel's=%d, requested=%d\n",
969          ((OOCapParams*)epCap->params)->txframes, noofframes);
970       if(((OOCapParams*)epCap->params)->txframes <= noofframes) {
971          return TRUE;
972       }
973       //else {
974       //   TODO: reduce our ep transmission rate, as peer EP has low receive
975       //   cap, than return TRUE
976       //}
977    }
978    return FALSE;
979
980 }
981
982
983 OOBOOL ooCapabilityCheckCompatibility_GSM
984    (OOH323CallData *call, ooH323EpCapability* epCap, 
985     H245AudioCapability* audioCap, int dir)
986 {
987    unsigned noofframes=0, cap;
988    switch(audioCap->t)
989    {
990    case T_H245AudioCapability_gsmFullRate:
991       cap = OO_GSMFULLRATE;
992       noofframes = (audioCap->u.gsmFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
993       break;
994    case T_H245AudioCapability_gsmHalfRate:
995       cap = OO_GSMHALFRATE;
996       noofframes = (audioCap->u.gsmHalfRate->audioUnitSize)/OO_GSMFRAMESIZE;
997       break;
998    case T_H245AudioCapability_gsmEnhancedFullRate:
999       cap = OO_GSMENHANCEDFULLRATE;
1000       noofframes = (audioCap->u.gsmEnhancedFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
1001       break;
1002    default:
1003       return FALSE;
1004    }
1005
1006    /* can we receive this capability */
1007    if(dir & OORX)
1008    {
1009       if(((OOGSMCapParams*)epCap->params)->rxframes >= noofframes)
1010          return TRUE;
1011    }
1012
1013    /* Make sure we transmit compatible stream */
1014    if(dir & OOTX)
1015    {
1016       if(((OOGSMCapParams*)epCap->params)->txframes > noofframes){
1017          OOTRACEDBGA5("Reducing txframes for GSM from %d to %d to match "
1018                       "receive capability of remote end.(%s, %s)\n", 
1019                      ((OOGSMCapParams*)epCap->params)->txframes, noofframes, 
1020                      call->callType, call->callToken);
1021          ((OOGSMCapParams*)epCap->params)->txframes = noofframes;
1022       }
1023       return TRUE;
1024    }
1025    return FALSE;
1026
1027 }
1028
1029
1030 OOBOOL ooCapabilityCheckCompatibility_H263Video
1031    (struct OOH323CallData *call, ooH323EpCapability *epCap, 
1032     H245VideoCapability *pVideoCap, int dir)
1033 {
1034    H245H263VideoCapability *pH263Cap = NULL;
1035
1036    OOH263CapParams *params = epCap->params;
1037    if(!pVideoCap->u.h263VideoCapability)  
1038    {
1039       OOTRACEERR3("Error:No H263 video capability present in video capability"
1040                  "structure. (%s, %s)\n", call->callType, call->callToken);
1041       return FALSE;
1042    }
1043    pH263Cap = pVideoCap->u.h263VideoCapability;
1044    
1045    /* can we receive/transmit this capability */
1046    if(OORX & dir)
1047    {
1048       if(pH263Cap->m.sqcifMPIPresent)
1049       {
1050          if(params->picFormat != OO_PICFORMAT_SQCIF)
1051          {
1052             return FALSE;
1053          }
1054          else{
1055             if(pH263Cap->sqcifMPI >= params->MPI)
1056                return TRUE;
1057             else
1058                return FALSE;
1059          }
1060       }
1061       if(pH263Cap->m.qcifMPIPresent)
1062       {
1063          if(params->picFormat != OO_PICFORMAT_QCIF)
1064          {
1065             return FALSE;
1066          }
1067          else{
1068             if(pH263Cap->qcifMPI >= params->MPI)
1069                return TRUE;
1070             else
1071                return FALSE;
1072          }
1073       }
1074       if(pH263Cap->m.cifMPIPresent)
1075       {
1076          if(params->picFormat != OO_PICFORMAT_CIF)
1077          {
1078             return FALSE;
1079          }
1080          else{
1081             if(pH263Cap->cifMPI >= params->MPI)
1082                return TRUE;
1083             else
1084                return FALSE;
1085          }
1086       }
1087       if(pH263Cap->m.cif4MPIPresent)
1088       {
1089          if(params->picFormat != OO_PICFORMAT_CIF4)
1090          {
1091             return FALSE;
1092          }
1093          else{
1094             if(pH263Cap->cif4MPI >= params->MPI)
1095                return TRUE;
1096             else
1097                return FALSE;
1098          }
1099       }
1100       if(pH263Cap->m.cif16MPIPresent)
1101       {
1102          if(params->picFormat != OO_PICFORMAT_CIF16)
1103          {
1104             return FALSE;
1105          }
1106          else{
1107             if(pH263Cap->cif16MPI >= params->MPI)
1108                return TRUE;
1109             else
1110                return FALSE;
1111          }
1112       }
1113    }
1114
1115    /* Can we transmit */
1116    if(OOTX & dir)
1117    {
1118        if(pH263Cap->m.sqcifMPIPresent)
1119       {
1120          if(params->picFormat != OO_PICFORMAT_SQCIF)
1121          {
1122             return FALSE;
1123          }
1124          else{
1125             if(pH263Cap->sqcifMPI <= params->MPI)
1126                return TRUE;
1127             else
1128                return FALSE;
1129          }
1130       }
1131       if(pH263Cap->m.qcifMPIPresent)
1132       {
1133          if(params->picFormat != OO_PICFORMAT_QCIF)
1134          {
1135             return FALSE;
1136          }
1137          else{
1138             if(pH263Cap->qcifMPI <= params->MPI)
1139                return TRUE;
1140             else
1141                return FALSE;
1142          }
1143       }
1144       if(pH263Cap->m.cifMPIPresent)
1145       {
1146          if(params->picFormat != OO_PICFORMAT_CIF)
1147          {
1148             return FALSE;
1149          }
1150          else{
1151             if(pH263Cap->cifMPI <= params->MPI)
1152                return TRUE;
1153             else
1154                return FALSE;
1155          }
1156       }
1157       if(pH263Cap->m.cif4MPIPresent)
1158       {
1159          if(params->picFormat != OO_PICFORMAT_CIF4)
1160          {
1161             return FALSE;
1162          }
1163          else{
1164             if(pH263Cap->cif4MPI <= params->MPI)
1165                return TRUE;
1166             else
1167                return FALSE;
1168          }
1169       }
1170       if(pH263Cap->m.cif16MPIPresent)
1171       {
1172          if(params->picFormat != OO_PICFORMAT_CIF16)
1173          {
1174             return FALSE;
1175          }
1176          else{
1177             if(pH263Cap->cif16MPI <= params->MPI)
1178                return TRUE;
1179             else
1180                return FALSE;
1181          }
1182       }
1183    }
1184    
1185    return FALSE;
1186
1187 }
1188
1189
1190 OOBOOL ooCapabilityCheckCompatibility_Audio
1191    (OOH323CallData *call, ooH323EpCapability* epCap, 
1192     H245AudioCapability* audioCap, int dir)
1193 {
1194
1195    switch(audioCap->t)
1196    {
1197    case T_H245AudioCapability_g711Ulaw56k:
1198    case T_H245AudioCapability_g711Ulaw64k:
1199    case T_H245AudioCapability_g711Alaw64k:
1200    case T_H245AudioCapability_g711Alaw56k:
1201    /*case T_H245AudioCapability_g726:*/
1202    case T_H245AudioCapability_g728:
1203    case T_H245AudioCapability_g729:
1204    case T_H245AudioCapability_g729AnnexA:
1205    case T_H245AudioCapability_g7231:
1206       return ooCapabilityCheckCompatibility_Simple(call, epCap, audioCap, dir);
1207    case T_H245AudioCapability_gsmFullRate:
1208       return ooCapabilityCheckCompatibility_GSM(call, epCap, audioCap, dir);
1209    default:
1210       return FALSE;
1211    }
1212
1213    return FALSE;  
1214 }
1215
1216 OOBOOL ooCapabilityCheckCompatibility_Video
1217    (OOH323CallData *call, ooH323EpCapability* epCap, 
1218     H245VideoCapability* videoCap, int dir)
1219 {
1220    switch(videoCap->t)
1221    {
1222    case T_H245VideoCapability_h263VideoCapability:
1223       return ooCapabilityCheckCompatibility_H263Video(call, epCap, 
1224                                                               videoCap, dir);
1225    default:
1226      OOTRACEDBGC3("ooCapabilityCheckCompatibility_Video - Unsupported video "
1227                   "capability. (%s, %s)\n", call->callType, call->callToken);
1228    }
1229    return FALSE;
1230 }
1231 /*
1232    Note: In faststart if we sent transmit rate (x>y) and remote
1233          can receive only y, then we can't reduce our transmit rate
1234 */
1235 OOBOOL ooCapabilityCheckCompatibility
1236    (struct OOH323CallData *call, ooH323EpCapability* epCap, 
1237     H245DataType* dataType, int dir)
1238 {
1239    switch(dataType->t)
1240    {
1241    case T_H245DataType_audioData:
1242       if(epCap->capType == OO_CAP_TYPE_AUDIO)
1243          return ooCapabilityCheckCompatibility_Audio(call, epCap, 
1244                                                    dataType->u.audioData, dir);
1245       break;
1246    case T_H245DataType_videoData:
1247       if(epCap->capType == OO_CAP_TYPE_VIDEO)
1248          return ooCapabilityCheckCompatibility_Video(call, epCap, 
1249                                                    dataType->u.videoData, dir);
1250       break;
1251    case T_H245DataType_data:
1252    default:
1253       OOTRACEDBGC3("ooCapabilityCheckCompatibility - Unsupported  "
1254                   "capability. (%s, %s)\n", call->callType, call->callToken);
1255    }
1256
1257    return FALSE;
1258 }
1259
1260 #if 0
1261 /**
1262   TODO: If txCap is local and number of txframes is greater than remote can
1263   receive, we should automatically decrease it. And logical channel cap should
1264   be the one where it should be decreased. The start logical channel will
1265   indicate the application that it is supposed to tx and a reduced rate.
1266  */
1267 ASN1BOOL ooCheckCompatibility
1268    (OOH323CallData *call, ooH323EpCapability *txCap, ooH323EpCapability *rxCap)
1269 {
1270
1271    if(txCap->cap != rxCap->cap) return FALSE;
1272
1273    if(!(txCap->dir & OOTX)) return FALSE;
1274    
1275    if(!(rxCap->dir & OORX)) return FALSE;
1276
1277    switch(txCap->cap)
1278    {   
1279    case OO_G711ALAW64K:
1280    case OO_G711ALAW56K:
1281    case OO_G711ULAW64K:
1282    case OO_G711ULAW56K:
1283    /*case OO_G726:*/
1284    case OO_G728:
1285    case OO_G729:
1286    case OO_G729A:
1287    case OO_G7231:
1288      if(((OOCapParams*)txCap->params)->txframes <= 
1289                                 ((OOCapParams*)rxCap->params)->rxframes)
1290        return TRUE;
1291      else{
1292        OOTRACEDBGA4("Simple caps %s are not compatible.(%s, %s)\n", 
1293                     ooGetCapTypeText(txCap->cap), call->callType, 
1294                     call->callToken);
1295        return FALSE;
1296      }
1297    case OO_GSMFULLRATE:
1298    case OO_GSMHALFRATE:
1299    case OO_GSMENHANCEDFULLRATE:
1300      if(((OOGSMCapParams*)txCap->params)->txframes <= 
1301                                 ((OOGSMCapParams*)rxCap->params)->rxframes)
1302        return TRUE;
1303      else{
1304        OOTRACEDBGA3("GSM caps are not compatible. (%s, %s)\n", call->callType,
1305                      call->callToken);
1306        return FALSE;
1307      }  
1308    default:
1309      OOTRACEWARN3("WARN: Unsupported capabilities being compared. (%s, %s)\n",
1310                    call->callType, call->callToken);
1311    }
1312    return FALSE;
1313
1314 }
1315
1316 #endif
1317
1318 ooH323EpCapability* ooIsAudioDataTypeGSMSupported
1319    (OOH323CallData *call, H245AudioCapability* audioCap, int dir)
1320 {
1321    unsigned framesPerPkt=0;
1322    int cap=0;
1323    ooH323EpCapability *cur = NULL, *epCap=NULL;
1324    OOGSMCapParams *params = NULL;
1325
1326    switch(audioCap->t)
1327    {
1328    case T_H245AudioCapability_gsmFullRate:
1329       framesPerPkt = (audioCap->u.gsmFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
1330       cap = OO_GSMFULLRATE;
1331       break;
1332    case T_H245AudioCapability_gsmHalfRate:
1333       framesPerPkt = (audioCap->u.gsmHalfRate->audioUnitSize)/OO_GSMFRAMESIZE;
1334       cap = OO_GSMHALFRATE;
1335       break;
1336    case T_H245AudioCapability_gsmEnhancedFullRate:
1337       framesPerPkt = (audioCap->u.gsmEnhancedFullRate->audioUnitSize)/OO_GSMFRAMESIZE;
1338       cap = OO_GSMENHANCEDFULLRATE;
1339       break;
1340    default:
1341       OOTRACEERR3("Error:Invalid GSM capability type.(%s, %s)\n", 
1342                                            call->callType, call->callToken);
1343      return NULL;
1344    }
1345
1346    OOTRACEDBGC4("Determined audio data type to be of type %d. Searching"
1347                 " for matching capability.(%s, %s)\n", cap, call->callType, 
1348                 call->callToken);
1349
1350    /* If we have call specific caps then we use them, otherwise we use
1351       general endpoint caps*/
1352    if(call->ourCaps)   
1353       cur = call->ourCaps;
1354    else
1355       cur = gH323ep.myCaps;
1356
1357    while(cur)
1358    {
1359       OOTRACEDBGC4("Local cap being compared %d. (%s, %s)\n", cur->cap,
1360                      call->callType, call->callToken);
1361       
1362       if(cur->cap == cap && (cur->dir & dir))
1363          break;
1364       cur = cur->next;
1365    }
1366    
1367    if(!cur) return NULL;
1368    
1369    OOTRACEDBGC4("Found matching audio capability type %d. Comparing"
1370                 " other parameters. (%s, %s)\n", cap, call->callType, 
1371                 call->callToken);
1372    
1373    /* can we receive this capability */
1374    if(dir & OORX)
1375    {
1376       if(((OOGSMCapParams*)cur->params)->rxframes < framesPerPkt)
1377          return NULL;
1378       else{
1379          epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1380                                                  sizeof(ooH323EpCapability));
1381          params =(OOGSMCapParams*)memAlloc(call->pctxt,sizeof(OOGSMCapParams));
1382          if(!epCap || !params)
1383          {
1384             OOTRACEERR3("Error:Memory - ooIsAudioDataTypeGSMSupported - "
1385                         "epCap/params (%s, %s)\n", call->callType, 
1386                         call->callToken);
1387             return NULL;
1388          }
1389          epCap->params = params;
1390          epCap->cap = cur->cap;
1391          epCap->dir = cur->dir;
1392          epCap->capType = cur->capType;
1393          epCap->startReceiveChannel = cur->startReceiveChannel;
1394          epCap->startTransmitChannel= cur->startTransmitChannel;
1395          epCap->stopReceiveChannel = cur->stopReceiveChannel;
1396          epCap->stopTransmitChannel = cur->stopTransmitChannel;
1397          epCap->next = NULL;
1398          memcpy(epCap->params, cur->params, sizeof(OOGSMCapParams));
1399          return epCap;
1400       }
1401    }
1402
1403    /* Can we transmit compatible stream */
1404    if(dir & OOTX)
1405    {
1406       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1407                                                 sizeof(ooH323EpCapability));
1408       params =(OOGSMCapParams*)memAlloc(call->pctxt,sizeof(OOGSMCapParams));
1409       if(!epCap || !params)
1410       {
1411          OOTRACEERR3("Error:Memory - ooIsAudioDataTypeGSMSupported - "
1412                      "epCap/params (%s, %s)\n", call->callType, 
1413                      call->callToken);
1414          return NULL;
1415       }
1416       epCap->params = params;
1417       epCap->cap = cur->cap;
1418       epCap->dir = cur->dir;
1419       epCap->capType = cur->capType;
1420       epCap->startReceiveChannel = cur->startReceiveChannel;
1421       epCap->startTransmitChannel= cur->startTransmitChannel;
1422       epCap->stopReceiveChannel = cur->stopReceiveChannel;
1423       epCap->stopTransmitChannel = cur->stopTransmitChannel;
1424       epCap->next = NULL;
1425       memcpy(epCap->params, cur->params, sizeof(OOGSMCapParams));
1426       if(params->txframes > framesPerPkt)
1427       {
1428          OOTRACEINFO5("Reducing framesPerPkt for transmission of GSM "
1429                       "capability from %d to %d to match receive capability of"
1430                       " remote endpoint.(%s, %s)\n", params->txframes, 
1431                       framesPerPkt, call->callType, call->callToken);
1432          params->txframes = framesPerPkt;
1433       }
1434
1435       return epCap;
1436
1437    }
1438    return NULL;
1439
1440 }
1441
1442 /* used for g711 ulaw/alaw, g728, g729, g729a, g7231 */
1443 ooH323EpCapability* ooIsAudioDataTypeSimpleSupported
1444    (OOH323CallData *call, H245AudioCapability* audioCap, int dir)
1445 {
1446    int cap, framesPerPkt=0;
1447    ooH323EpCapability *cur=NULL, *epCap=NULL;
1448    OOCapParams * params= NULL;
1449
1450    /* Find similar capability */
1451    switch(audioCap->t)
1452    {
1453       case T_H245AudioCapability_g711Alaw64k:
1454          framesPerPkt = audioCap->u.g711Alaw64k;
1455          cap = OO_G711ALAW64K;
1456          break;
1457       case T_H245AudioCapability_g711Alaw56k:
1458          framesPerPkt = audioCap->u.g711Alaw56k;
1459          cap = OO_G711ALAW56K;
1460          break;
1461       case T_H245AudioCapability_g711Ulaw56k:
1462          framesPerPkt = audioCap->u.g711Ulaw56k;
1463          cap = OO_G711ULAW56K;
1464          break;
1465       case T_H245AudioCapability_g711Ulaw64k:
1466          framesPerPkt = audioCap->u.g711Ulaw64k;
1467          cap = OO_G711ULAW64K;
1468          break;
1469
1470 /*      case T_H245AudioCapability_g726:
1471          framesPerPkt = audioCap->u.g726;
1472          cap = OO_G726;
1473          break;
1474 */
1475       case T_H245AudioCapability_g728:
1476          framesPerPkt = audioCap->u.g728;
1477          cap = OO_G728;
1478          break;
1479
1480       case T_H245AudioCapability_g729:
1481          framesPerPkt = audioCap->u.g729;
1482          cap = OO_G729;
1483          break;
1484       case T_H245AudioCapability_g729AnnexA:
1485          framesPerPkt = audioCap->u.g729AnnexA;
1486          cap = OO_G729A;
1487          break;
1488       case T_H245AudioCapability_g7231:
1489          framesPerPkt = audioCap->u.g7231->maxAl_sduAudioFrames;
1490          cap = OO_G7231;
1491          break;
1492       default:
1493          return NULL;
1494    }
1495
1496    OOTRACEDBGC4("Determined Simple audio data type to be of type %s. Searching"
1497                 " for matching capability.(%s, %s)\n", 
1498                 ooGetCapTypeText(cap), call->callType, call->callToken);
1499
1500    /* If we have call specific caps, we use them; otherwise use general
1501       endpoint caps
1502    */   
1503    if(call->ourCaps)
1504      cur = call->ourCaps;
1505    else
1506      cur = gH323ep.myCaps;
1507
1508    while(cur)
1509    {
1510       OOTRACEDBGC4("Local cap being compared %s. (%s, %s)\n", 
1511          ooGetCapTypeText(cur->cap),call->callType, call->callToken);
1512       
1513       if(cur->cap == cap && (cur->dir & dir))
1514          break;
1515       cur = cur->next;
1516    }
1517    
1518    if(!cur) return NULL;
1519    
1520    OOTRACEDBGC4("Found matching simple audio capability type %s. Comparing"
1521                 " other parameters. (%s, %s)\n", ooGetCapTypeText(cap), 
1522                 call->callType, call->callToken);
1523    
1524    /* can we receive this capability */
1525    if(dir & OORX)
1526    {
1527      if(((OOCapParams*)cur->params)->rxframes < framesPerPkt)
1528          return NULL;
1529      else{
1530         OOTRACEDBGC4("We can receive Simple capability %s. (%s, %s)\n", 
1531                       ooGetCapTypeText(cur->cap), call->callType, 
1532                       call->callToken);
1533         epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1534                                                  sizeof(ooH323EpCapability));
1535         params=(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
1536         if(!epCap || !params)
1537         {
1538            OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
1539                        "epCap/params (%s, %s)\n", call->callType, 
1540                        call->callToken);
1541            return NULL;
1542         }
1543         epCap->params = params;
1544         epCap->cap = cur->cap;
1545         epCap->dir = cur->dir;
1546         epCap->capType = cur->capType;
1547         epCap->startReceiveChannel = cur->startReceiveChannel;
1548         epCap->startTransmitChannel= cur->startTransmitChannel;
1549         epCap->stopReceiveChannel = cur->stopReceiveChannel;
1550         epCap->stopTransmitChannel = cur->stopTransmitChannel;
1551         epCap->next = NULL;
1552         memcpy(epCap->params, cur->params, sizeof(OOCapParams));
1553         OOTRACEDBGC4("Returning copy of matched receive capability %s. "
1554                      "(%s, %s)\n", 
1555                      ooGetCapTypeText(cur->cap), call->callType, 
1556                      call->callToken);
1557         return epCap;
1558      }
1559    }
1560
1561    /* Can we transmit compatible stream */
1562    if(dir & OOTX)
1563    {
1564       OOTRACEDBGC4("We can transmit Simple capability %s. (%s, %s)\n", 
1565                    ooGetCapTypeText(cur->cap), call->callType, 
1566                    call->callToken);
1567       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1568                                                 sizeof(ooH323EpCapability));
1569       params =(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
1570       if(!epCap || !params)
1571       {
1572          OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
1573                      "epCap/params (%s, %s)\n", call->callType, 
1574                      call->callToken);
1575          return NULL;
1576       }
1577       epCap->params = params;
1578       epCap->cap = cur->cap;
1579       epCap->dir = cur->dir;
1580       epCap->capType = cur->capType;
1581       epCap->startReceiveChannel = cur->startReceiveChannel;
1582       epCap->startTransmitChannel= cur->startTransmitChannel;
1583       epCap->stopReceiveChannel = cur->stopReceiveChannel;
1584       epCap->stopTransmitChannel = cur->stopTransmitChannel;
1585       epCap->next = NULL;
1586       memcpy(epCap->params, cur->params, sizeof(OOCapParams));
1587       if(params->txframes > framesPerPkt)
1588       {
1589          OOTRACEINFO5("Reducing framesPerPkt for transmission of Simple "
1590                       "capability from %d to %d to match receive capability of"
1591                       " remote endpoint.(%s, %s)\n", params->txframes, 
1592                       framesPerPkt, call->callType, call->callToken);
1593          params->txframes = framesPerPkt;
1594       }
1595       OOTRACEDBGC4("Returning copy of matched transmit capability %s."
1596                    "(%s, %s)\n", 
1597                    ooGetCapTypeText(cur->cap), call->callType, 
1598                    call->callToken);
1599       return epCap;
1600    }
1601    return NULL;
1602 }
1603
1604
1605
1606 ooH323EpCapability* ooIsAudioDataTypeSupported
1607    (OOH323CallData *call, H245AudioCapability* audioCap, int dir)
1608 {
1609    /* Find similar capability */
1610    switch(audioCap->t)
1611    {
1612       case T_H245AudioCapability_g711Alaw64k:
1613       case T_H245AudioCapability_g711Alaw56k:
1614       case T_H245AudioCapability_g711Ulaw56k:
1615       case T_H245AudioCapability_g711Ulaw64k:
1616       /*case T_H245AudioCapability_g726:*/
1617       case T_H245AudioCapability_g728:
1618       case T_H245AudioCapability_g729:
1619       case T_H245AudioCapability_g729AnnexA:
1620       case T_H245AudioCapability_g7231:
1621          return ooIsAudioDataTypeSimpleSupported(call, audioCap, dir);
1622       case T_H245AudioCapability_gsmFullRate:
1623       case T_H245AudioCapability_gsmHalfRate:
1624       case T_H245AudioCapability_gsmEnhancedFullRate:
1625          return ooIsAudioDataTypeGSMSupported(call, audioCap, dir);   
1626       default:
1627          return NULL;
1628    }   
1629 }
1630
1631
1632 ooH323EpCapability* ooIsVideoDataTypeH263Supported
1633    (OOH323CallData *call, H245H263VideoCapability* pH263Cap, int dir, 
1634     OOPictureFormat picFormat)
1635 {
1636    int cap;
1637    ooH323EpCapability *cur=NULL, *epCap=NULL;
1638    OOH263CapParams *params= NULL;   
1639    char *pictureType=NULL;
1640    unsigned mpi=0;
1641    cap = OO_H263VIDEO;
1642
1643    if(picFormat == OO_PICFORMAT_SQCIF && pH263Cap->m.sqcifMPIPresent)
1644    {
1645       pictureType = "SQCIF";
1646       mpi = pH263Cap->sqcifMPI;
1647    }
1648    if(picFormat == OO_PICFORMAT_QCIF && pH263Cap->m.qcifMPIPresent)
1649    {
1650       pictureType = "QCIF";
1651       mpi = pH263Cap->qcifMPI;
1652    }
1653    if(picFormat == OO_PICFORMAT_CIF && pH263Cap->m.cifMPIPresent)
1654    {
1655       pictureType = "CIF";
1656       mpi = pH263Cap->cifMPI;
1657    }
1658    if(picFormat == OO_PICFORMAT_CIF4 && pH263Cap->m.cif4MPIPresent)
1659    {
1660       pictureType = "CIF4";
1661       mpi = pH263Cap->cif4MPI;
1662    }
1663    if(picFormat == OO_PICFORMAT_CIF16 && pH263Cap->m.cif16MPIPresent)
1664    {
1665       pictureType = "CIF16";
1666       mpi = pH263Cap->cif16MPI;
1667    }
1668    
1669
1670    OOTRACEDBGA4("Looking for H263 video capability(%s). (%s, %s)\n", 
1671                  pictureType, call->callType, call->callToken);
1672
1673   /* If we have call specific caps, we use them; otherwise use general
1674       endpoint caps
1675    */   
1676    if(call->ourCaps)
1677      cur = call->ourCaps;
1678    else
1679      cur = gH323ep.myCaps;
1680
1681    while(cur)
1682    {
1683       OOTRACEDBGC4("Local cap being compared %s. (%s, %s)\n", 
1684               ooGetCapTypeText(cur->cap),call->callType, call->callToken);
1685       
1686       if(cur->cap == cap && (cur->dir & dir))
1687       {
1688          if(((OOH263CapParams*)cur->params)->picFormat == picFormat)
1689             break;
1690       }
1691       cur = cur->next;
1692    }
1693    
1694    if(!cur) return NULL;
1695    
1696    OOTRACEDBGC4("Found matching H.263 video capability type %s. Comparing"
1697                 " other parameters. (%s, %s)\n", ooGetCapTypeText(cap), 
1698                 call->callType, call->callToken);   
1699    if(dir & OORX)
1700    {
1701       if(mpi < ((OOH263CapParams*)cur->params)->MPI)
1702          return NULL;
1703       else{
1704          epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1705                                                    sizeof(ooH323EpCapability));
1706          params = (OOH263CapParams*) memAlloc(call->pctxt, 
1707                                                       sizeof(OOH263CapParams));
1708          if(!epCap || !params)
1709          {
1710             OOTRACEERR3("Error:Memory - ooIsVideoDataTypeH263Supported - "
1711                        "epCap/params. (%s, %s)\n", call->callType, 
1712                         call->callToken);
1713             return NULL;
1714          }
1715          epCap->params = params;
1716          epCap->cap = cur->cap;
1717          epCap->dir = cur->dir;
1718          epCap->capType = cur->capType;
1719          epCap->startReceiveChannel = cur->startReceiveChannel;
1720          epCap->startTransmitChannel= cur->startTransmitChannel;
1721          epCap->stopReceiveChannel = cur->stopReceiveChannel;
1722          epCap->stopTransmitChannel = cur->stopTransmitChannel;
1723          epCap->next = NULL;
1724          memcpy(epCap->params, cur->params, sizeof(OOH263CapParams));
1725          OOTRACEDBGC4("Returning copy of matched receive capability %s. "
1726                      "(%s, %s)\n", ooGetCapTypeText(cur->cap), call->callType, 
1727                      call->callToken);
1728          return epCap;
1729       }
1730    }
1731    if(dir & OOTX)
1732    {
1733       epCap = (ooH323EpCapability*)memAlloc(call->pctxt, 
1734                                                   sizeof(ooH323EpCapability));
1735       params = (OOH263CapParams*) memAlloc(call->pctxt, 
1736                                                       sizeof(OOH263CapParams));
1737       if(!epCap || !params)
1738       {
1739          OOTRACEERR3("Error:Memory - ooIsVideoDataTypeH263Supported - "
1740                      "epCap/params. (%s, %s)\n", call->callType, 
1741                      call->callToken);
1742          return NULL;
1743       }
1744       epCap->params = params;
1745       epCap->cap = cur->cap;
1746       epCap->dir = cur->dir;
1747       epCap->capType = cur->capType;
1748       epCap->startReceiveChannel = cur->startReceiveChannel;
1749       epCap->startTransmitChannel= cur->startTransmitChannel;
1750       epCap->stopReceiveChannel = cur->stopReceiveChannel;
1751       epCap->stopTransmitChannel = cur->stopTransmitChannel;
1752       epCap->next = NULL;
1753       memcpy(epCap->params, cur->params, sizeof(OOH263CapParams));
1754       if(params->MPI < mpi)
1755       {
1756          OOTRACEINFO5("Increasing minimum picture interval for transmission of"
1757                       " H263 video capability from %d to %d to match receive "
1758                       "capability of remote endpoint.(%s, %s)\n", params->MPI, 
1759                       mpi, call->callType, call->callToken);
1760          params->MPI = mpi;
1761       }
1762       OOTRACEDBGC4("Returning copy of matched receive capability %s. "
1763                   "(%s, %s)\n", ooGetCapTypeText(cur->cap), call->callType, 
1764                   call->callToken);
1765       return epCap;
1766    }
1767    return NULL;
1768
1769 }
1770
1771 ooH323EpCapability* ooIsVideoDataTypeSupported
1772    (OOH323CallData *call, H245VideoCapability* pVideoCap, int dir)
1773 {
1774    switch(pVideoCap->t)   
1775    {
1776    case T_H245VideoCapability_h263VideoCapability:
1777       if(pVideoCap->u.h263VideoCapability->m.sqcifMPIPresent)
1778          return ooIsVideoDataTypeH263Supported(call, 
1779                     pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_SQCIF);
1780       else if(pVideoCap->u.h263VideoCapability->m.qcifMPIPresent)
1781          return ooIsVideoDataTypeH263Supported(call, 
1782                      pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_QCIF);
1783       else if(pVideoCap->u.h263VideoCapability->m.cifMPIPresent)
1784         return ooIsVideoDataTypeH263Supported(call, 
1785                       pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_CIF);
1786       else if(pVideoCap->u.h263VideoCapability->m.cif4MPIPresent)
1787         return ooIsVideoDataTypeH263Supported(call, 
1788                      pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_CIF4);
1789       else if(pVideoCap->u.h263VideoCapability->m.cif16MPIPresent)
1790         return ooIsVideoDataTypeH263Supported(call, 
1791                     pVideoCap->u.h263VideoCapability, dir, OO_PICFORMAT_CIF16);
1792       break;  
1793    case T_H245VideoCapability_nonStandard:
1794    case T_H245VideoCapability_h261VideoCapability:
1795    case T_H245VideoCapability_h262VideoCapability:
1796    case T_H245VideoCapability_is11172VideoCapability:
1797    case T_H245VideoCapability_genericVideoCapability:
1798    case T_H245VideoCapability_extElem1:
1799    default:
1800      OOTRACEDBGA1("Unsupported video capability type in "
1801                   "ooIsVideoDataTypeSupported\n");
1802       return NULL;
1803    }
1804    return NULL;
1805 }
1806
1807 ooH323EpCapability* ooIsDataTypeSupported
1808                    (OOH323CallData *call, H245DataType *data, int dir)
1809 {
1810    OOTRACEDBGC3("Looking for data type support. (%s, %s)\n", call->callType, 
1811                  call->callToken);
1812     
1813    switch(data->t)
1814    {
1815    case T_H245DataType_nonStandard:
1816       OOTRACEDBGC3("NonStandard data type not supported.(%s, %s)\n", 
1817                    call->callType, call->callToken);
1818       return NULL;
1819    case T_H245DataType_nullData:
1820       OOTRACEDBGC3("Null data type not supported.(%s, %s)\n", 
1821                    call->callType, call->callToken);
1822       return NULL;
1823    case T_H245DataType_videoData:
1824       OOTRACEDBGC3("Looking for video dataType support. (%s, %s)\n",
1825                     call->callType, call->callToken);
1826       return ooIsVideoDataTypeSupported(call, data->u.videoData, dir);
1827    case T_H245DataType_audioData:
1828       OOTRACEDBGC3("Looking for audio dataType support. (%s, %s)\n",
1829                     call->callType, call->callToken);
1830       return ooIsAudioDataTypeSupported(call, data->u.audioData, dir);
1831    case T_H245DataType_data:
1832      OOTRACEDBGC3("Data type not supported.(%s, %s)\n", 
1833                    call->callType, call->callToken);
1834      return NULL;
1835    case T_H245DataType_encryptionData:
1836      OOTRACEDBGC3("Encryption data type not supported.(%s, %s)\n", 
1837                    call->callType, call->callToken);
1838      return NULL;
1839    case T_H245DataType_h235Control:
1840      return NULL;
1841    case T_H245DataType_h235Media:
1842      return NULL;
1843    case T_H245DataType_multiplexedStream:
1844      return NULL;
1845    default:
1846       OOTRACEINFO3("Unknown data type (%s, %s)\n", call->callType, 
1847                     call->callToken);
1848    }
1849    return NULL;
1850 }
1851
1852 int ooResetCapPrefs(OOH323CallData *call)
1853 {
1854    OOCapPrefs *capPrefs=NULL;
1855    if(call)
1856       capPrefs = &call->capPrefs;
1857    else
1858       capPrefs = &gH323ep.capPrefs;
1859    memset(capPrefs, 0, sizeof(OOCapPrefs));
1860    return OO_OK;
1861 }
1862
1863 int ooRemoveCapFromCapPrefs(OOH323CallData *call, int cap)
1864 {
1865    int i=0, j=0;
1866    OOCapPrefs *capPrefs=NULL, oldPrefs;
1867    if(call)
1868       capPrefs = &call->capPrefs;
1869    else
1870       capPrefs = &gH323ep.capPrefs;
1871
1872    memcpy(&oldPrefs, capPrefs, sizeof(OOCapPrefs));
1873    memset(capPrefs, 0, sizeof(OOCapPrefs));
1874    for(i=0; i<oldPrefs.index; i++)
1875    {  
1876       if(oldPrefs.order[i] != cap) 
1877          capPrefs->order[j++] = oldPrefs.order[i];
1878    }
1879    capPrefs->index = j;
1880    return OO_OK;
1881 }
1882
1883  
1884 int ooAppendCapToCapPrefs(OOH323CallData *call, int cap)
1885 {
1886    OOCapPrefs *capPrefs=NULL;
1887    if(call)
1888       capPrefs = &call->capPrefs;
1889    else
1890       capPrefs = &gH323ep.capPrefs;
1891
1892    capPrefs->order[capPrefs->index++] = cap;
1893    return OO_OK;
1894 }
1895
1896 int ooChangeCapPrefOrder(OOH323CallData *call, int cap, int pos)
1897 {
1898    int i=0, j=0;
1899    OOCapPrefs *capPrefs = NULL;
1900
1901    /* Whether to change prefs for call or for endpoint as a whole */
1902    if(call)
1903       capPrefs = &call->capPrefs;
1904    else
1905       capPrefs = &gH323ep.capPrefs;
1906
1907    /* check whether cap exists, cap must exist */
1908    for(i=0; i<capPrefs->index; i++)
1909    {
1910       if(capPrefs->order[i] == cap)
1911          break;
1912    }
1913    if(i == capPrefs->index) return OO_FAILED;
1914
1915    if(i==pos) return OO_OK; /* No need to change */
1916
1917    /* Decrease Pref order */
1918    if(i < pos)
1919    {
1920       for( ; i<pos; i++) 
1921          capPrefs->order[i] = capPrefs->order[i+1];
1922       capPrefs->order[i]=cap;
1923       return OO_OK;
1924    }
1925    /* Increase Pref order */
1926    if(i>pos)
1927    {
1928      for(j=i; j>pos; j--)
1929        capPrefs->order[j] = capPrefs->order[j-1];
1930      capPrefs->order[j] = cap;
1931      return OO_OK;
1932    }
1933
1934    return OO_FAILED;
1935
1936 }
1937
1938 int ooPreppendCapToCapPrefs(OOH323CallData *call, int cap)
1939 {
1940    int i=0, j=0;
1941    OOCapPrefs *capPrefs=NULL, oldPrefs;
1942    if(call)
1943       capPrefs = &call->capPrefs;
1944    else
1945       capPrefs = &gH323ep.capPrefs;
1946
1947    memcpy(&oldPrefs, capPrefs, sizeof(OOCapPrefs));
1948
1949  
1950    capPrefs->order[j++] = cap;
1951
1952    for(i=0; i<oldPrefs.index; i++)
1953    {  
1954       if(oldPrefs.order[i] != cap) 
1955          capPrefs->order[j++] = oldPrefs.order[i];
1956    }
1957    capPrefs->index = j;
1958    return OO_OK;
1959 }
1960
1961        
1962 int ooAddRemoteCapability(OOH323CallData *call, H245Capability *cap)
1963 {
1964    switch(cap->t)
1965    {
1966    case T_H245Capability_receiveAudioCapability:
1967      return ooAddRemoteAudioCapability(call, cap->u.receiveAudioCapability, 
1968                                        OORX);
1969    case T_H245Capability_transmitAudioCapability:
1970      return ooAddRemoteAudioCapability(call, cap->u.transmitAudioCapability, 
1971                                        OOTX);
1972    case T_H245Capability_receiveAndTransmitAudioCapability:
1973      return ooAddRemoteAudioCapability(call, 
1974                              cap->u.receiveAndTransmitAudioCapability, OORXTX);
1975    default:
1976      OOTRACEDBGA3("Unsupported cap type encountered. Ignoring. (%s, %s)\n", 
1977                    call->callType, call->callToken);
1978    }
1979    return OO_OK;
1980 }
1981
1982 int ooAddRemoteAudioCapability(OOH323CallData *call, 
1983                                H245AudioCapability *audioCap,
1984                                int dir)
1985 {
1986    int rxframes=0, txframes=0;
1987   
1988    switch(audioCap->t)
1989    {
1990    case T_H245AudioCapability_g711Alaw64k:
1991       if(dir&OOTX) txframes = audioCap->u.g711Alaw64k;
1992       else if(dir&OORX) rxframes = audioCap->u.g711Alaw64k;
1993       else{ 
1994          txframes = audioCap->u.g711Alaw64k; 
1995          rxframes = audioCap->u.g711Alaw64k; 
1996       }
1997       return ooCapabilityAddSimpleCapability(call, OO_G711ALAW64K, txframes, 
1998                             rxframes, FALSE, dir, NULL, NULL, NULL, NULL,TRUE);
1999    case T_H245AudioCapability_g711Alaw56k:
2000       if(dir&OOTX) txframes = audioCap->u.g711Alaw56k;
2001       else if(dir&OORX) rxframes = audioCap->u.g711Alaw56k;
2002       else{ 
2003          txframes = audioCap->u.g711Alaw56k; 
2004          rxframes = audioCap->u.g711Alaw56k; 
2005       }
2006       return ooCapabilityAddSimpleCapability(call, OO_G711ALAW56K, txframes, 
2007                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2008    case T_H245AudioCapability_g711Ulaw64k:
2009       if(dir&OOTX) txframes = audioCap->u.g711Ulaw64k;
2010       else if(dir&OORX) rxframes = audioCap->u.g711Ulaw64k;
2011       else{ 
2012          txframes = audioCap->u.g711Ulaw64k; 
2013          rxframes = audioCap->u.g711Ulaw64k; 
2014       }
2015       return ooCapabilityAddSimpleCapability(call, OO_G711ULAW64K, txframes, 
2016                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2017    case T_H245AudioCapability_g711Ulaw56k:
2018       if(dir&OOTX) txframes = audioCap->u.g711Ulaw56k;
2019       else if(dir&OORX) rxframes = audioCap->u.g711Ulaw56k;
2020       else{ 
2021          txframes = audioCap->u.g711Ulaw56k; 
2022          rxframes = audioCap->u.g711Ulaw56k; 
2023       }
2024       return ooCapabilityAddSimpleCapability(call, OO_G711ULAW56K, txframes, 
2025                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2026
2027 /*   case T_H245AudioCapability_g726:
2028       if(dir&OOTX) txframes = audioCap->u.g726;
2029       else if(dir&OORX) rxframes = audioCap->u.g726;
2030       else{ 
2031          txframes = audioCap->u.g726; 
2032          rxframes = audioCap->u.g726; 
2033       }
2034       return ooCapabilityAddSimpleCapability(call, OO_G726, txframes, 
2035                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2036 */
2037    case T_H245AudioCapability_g728:
2038       if(dir&OOTX) txframes = audioCap->u.g728;
2039       else if(dir&OORX) rxframes = audioCap->u.g728;
2040       else{ 
2041          txframes = audioCap->u.g728; 
2042          rxframes = audioCap->u.g728; 
2043       }
2044       return ooCapabilityAddSimpleCapability(call, OO_G728, txframes, 
2045                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2046
2047    case T_H245AudioCapability_g729:
2048       if(dir&OOTX) txframes = audioCap->u.g729;
2049       else if(dir&OORX) rxframes = audioCap->u.g729;
2050       else{ 
2051          txframes = audioCap->u.g729; 
2052          rxframes = audioCap->u.g729; 
2053       }
2054       return ooCapabilityAddSimpleCapability(call, OO_G729, txframes, 
2055                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2056
2057    case T_H245AudioCapability_g729AnnexA:
2058       if(dir&OOTX) txframes = audioCap->u.g729AnnexA;
2059       else if(dir&OORX) rxframes = audioCap->u.g729AnnexA;
2060       else{ 
2061          txframes = audioCap->u.g729AnnexA; 
2062          rxframes = audioCap->u.g729AnnexA; 
2063       }
2064       return ooCapabilityAddSimpleCapability(call, OO_G729A, txframes, 
2065                            rxframes, FALSE, dir, NULL, NULL, NULL, NULL, TRUE);
2066
2067    case T_H245AudioCapability_g7231:
2068       if(dir&OOTX) txframes = audioCap->u.g7231->maxAl_sduAudioFrames;
2069       else if(dir&OORX) rxframes = audioCap->u.g7231->maxAl_sduAudioFrames;
2070       else{ 
2071          txframes = audioCap->u.g7231->maxAl_sduAudioFrames; 
2072          rxframes = audioCap->u.g7231->maxAl_sduAudioFrames; 
2073       }
2074       return ooCapabilityAddSimpleCapability(call, OO_G7231, txframes,rxframes,
2075                                          audioCap->u.g7231->silenceSuppression,
2076                                          dir, NULL, NULL, NULL, NULL, TRUE); 
2077    case T_H245AudioCapability_gsmFullRate:
2078       return ooCapabilityAddGSMCapability(call, OO_GSMFULLRATE, 
2079             (unsigned)(audioCap->u.gsmFullRate->audioUnitSize/OO_GSMFRAMESIZE),
2080                                         audioCap->u.gsmFullRate->comfortNoise,
2081                                         audioCap->u.gsmFullRate->scrambled, 
2082                                         dir, NULL, NULL, NULL, NULL, TRUE);
2083    case T_H245AudioCapability_gsmHalfRate:
2084       return ooCapabilityAddGSMCapability(call, OO_GSMHALFRATE,
2085             (unsigned)(audioCap->u.gsmHalfRate->audioUnitSize/OO_GSMFRAMESIZE),
2086                                         audioCap->u.gsmHalfRate->comfortNoise,
2087                                         audioCap->u.gsmHalfRate->scrambled, 
2088                                         dir, NULL, NULL, NULL, NULL, TRUE);
2089    case T_H245AudioCapability_gsmEnhancedFullRate:
2090       return ooCapabilityAddGSMCapability(call, OO_GSMENHANCEDFULLRATE, 
2091    (unsigned)(audioCap->u.gsmEnhancedFullRate->audioUnitSize/OO_GSMFRAMESIZE),
2092                                 audioCap->u.gsmEnhancedFullRate->comfortNoise,
2093                                 audioCap->u.gsmEnhancedFullRate->scrambled, 
2094                                 dir, NULL, NULL, NULL, NULL, TRUE);
2095
2096    default:
2097      OOTRACEDBGA1("Unsupported audio capability type\n");
2098    
2099    }
2100
2101    return OO_OK;
2102 }
2103
2104
2105
2106
2107
2108 int ooCapabilityUpdateJointCapabilities
2109    (OOH323CallData* call, H245Capability *cap)
2110 {
2111    ooH323EpCapability * epCap = NULL, *cur = NULL;
2112    OOTRACEDBGC3("checking whether we need to add cap to joint capabilities"
2113                 "(%s, %s)\n", call->callType, call->callToken);
2114             
2115    switch(cap->t)
2116    {
2117    case T_H245Capability_receiveAudioCapability:
2118       epCap= ooIsAudioDataTypeSupported(call, cap->u.receiveAudioCapability, 
2119                                         OOTX);
2120       break;
2121    case T_H245Capability_transmitAudioCapability:
2122       epCap = ooIsAudioDataTypeSupported(call, cap->u.transmitAudioCapability,
2123                                         OORX);
2124       break;
2125    case T_H245Capability_receiveAndTransmitAudioCapability:
2126       epCap = NULL;
2127       break;
2128    case T_H245Capability_receiveVideoCapability:
2129       return ooCapabilityUpdateJointCapabilitiesVideo(call, 
2130                                           cap->u.receiveVideoCapability, OOTX);
2131    case T_H245Capability_transmitVideoCapability:
2132       return ooCapabilityUpdateJointCapabilitiesVideo(call, 
2133                                          cap->u.transmitVideoCapability, OORX);
2134    case T_H245Capability_receiveUserInputCapability:
2135       if((cap->u.receiveUserInputCapability->t == 
2136                                  T_H245UserInputCapability_basicString) &&
2137          (call->dtmfmode & OO_CAP_DTMF_H245_alphanumeric))
2138       {
2139          call->jointDtmfMode |= OO_CAP_DTMF_H245_alphanumeric;
2140          return OO_OK;
2141       }
2142       else if((cap->u.receiveUserInputCapability->t ==
2143                T_H245UserInputCapability_dtmf) &&
2144                (call->dtmfmode & OO_CAP_DTMF_H245_signal))
2145       {
2146          call->jointDtmfMode |= OO_CAP_DTMF_H245_signal;
2147          return OO_OK;
2148       }
2149       //break;
2150    default:
2151      OOTRACEDBGA3("Unsupported cap type encountered. Ignoring. (%s, %s)\n", 
2152                    call->callType, call->callToken);
2153    }
2154
2155    if(epCap)
2156    {
2157       OOTRACEDBGC3("Adding cap to joint capabilities(%s, %s)\n",call->callType,
2158                    call->callToken);
2159       /* Note:we add jointCaps in remote endpoints preference order.*/
2160       if(!call->jointCaps)
2161          call->jointCaps = epCap;
2162       else {
2163          cur = call->jointCaps;
2164          while(cur->next) cur = cur->next;
2165          cur->next = epCap;
2166       }
2167
2168       return OO_OK;
2169    }
2170
2171    OOTRACEDBGC3("Not adding to joint capabilities. (%s, %s)\n", call->callType,
2172                 call->callToken);
2173    return OO_OK;
2174 }
2175
2176
2177
2178 int ooCapabilityUpdateJointCapabilitiesVideo
2179    (OOH323CallData *call, H245VideoCapability *videoCap, int dir)
2180 {
2181    switch(videoCap->t)
2182    {
2183    case T_H245VideoCapability_h263VideoCapability:
2184       return ooCapabilityUpdateJointCapabilitiesVideoH263(call, 
2185                                         videoCap->u.h263VideoCapability, dir);
2186    default:
2187       OOTRACEDBGC3("ooCapabilityUpdateJointCapabilitiesVideo - Unsupported"
2188                    "capability type. (%s, %s)\n", call->callType, 
2189                    call->callToken);
2190    }
2191    return OO_OK;
2192 }
2193
2194
2195 int ooCapabilityUpdateJointCapabilitiesVideoH263
2196    (OOH323CallData *call, H245H263VideoCapability *pH263Cap, int dir)
2197 {
2198    ooH323EpCapability *epCap = NULL, *cur = NULL;
2199    if(pH263Cap->m.sqcifMPIPresent)
2200    {
2201       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
2202                                                           OO_PICFORMAT_SQCIF);
2203       if(epCap)
2204       {
2205          OOTRACEDBGC3("Adding H263-SQCIF to joint capabilities(%s, %s)\n",
2206                       call->callType, call->callToken);
2207          /* Note:we add jointCaps in remote endpoints preference order.*/
2208          if(!call->jointCaps)
2209             call->jointCaps = epCap;
2210          else {
2211             cur = call->jointCaps;
2212             while(cur->next) cur = cur->next;
2213             cur->next = epCap;
2214          }
2215
2216       }     
2217    }
2218
2219    epCap = NULL;
2220
2221    if(pH263Cap->m.qcifMPIPresent)
2222    {
2223       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
2224                                                           OO_PICFORMAT_QCIF);
2225       if(epCap)
2226       {
2227          OOTRACEDBGC3("Adding H263-QCIF to joint capabilities(%s, %s)\n",
2228                       call->callType, call->callToken);
2229          /* Note:we add jointCaps in remote endpoints preference order.*/
2230          if(!call->jointCaps)
2231             call->jointCaps = epCap;
2232          else {
2233             cur = call->jointCaps;
2234             while(cur->next) cur = cur->next;
2235             cur->next = epCap;
2236          }
2237
2238       }     
2239    }
2240
2241    epCap = NULL;
2242
2243    if(pH263Cap->m.cifMPIPresent)
2244    {
2245       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
2246                                                           OO_PICFORMAT_CIF);
2247       if(epCap)
2248       {
2249          OOTRACEDBGC3("Adding H263-CIF to joint capabilities(%s, %s)\n",
2250                       call->callType, call->callToken);
2251          /* Note:we add jointCaps in remote endpoints preference order.*/
2252          if(!call->jointCaps)
2253             call->jointCaps = epCap;
2254          else {
2255             cur = call->jointCaps;
2256             while(cur->next) cur = cur->next;
2257             cur->next = epCap;
2258          }
2259
2260       }     
2261    }
2262
2263    epCap = NULL;
2264
2265    if(pH263Cap->m.cif4MPIPresent)
2266    {
2267       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
2268                                                           OO_PICFORMAT_CIF4);
2269       if(epCap)
2270       {
2271          OOTRACEDBGC3("Adding H263-CIF4 to joint capabilities(%s, %s)\n",
2272                       call->callType, call->callToken);
2273          /* Note:we add jointCaps in remote endpoints preference order.*/
2274          if(!call->jointCaps)
2275             call->jointCaps = epCap;
2276          else {
2277             cur = call->jointCaps;
2278             while(cur->next) cur = cur->next;
2279             cur->next = epCap;
2280          }
2281       }     
2282    }
2283
2284    epCap = NULL;
2285
2286    if(pH263Cap->m.cif16MPIPresent)
2287    {
2288       epCap =  ooIsVideoDataTypeH263Supported(call, pH263Cap, dir, 
2289                                                           OO_PICFORMAT_CIF16);
2290       if(epCap)
2291       {
2292          OOTRACEDBGC3("Adding H263-CIF16 to joint capabilities(%s, %s)\n",
2293                       call->callType, call->callToken);
2294          /* Note:we add jointCaps in remote endpoints preference order.*/
2295          if(!call->jointCaps)
2296             call->jointCaps = epCap;
2297          else {
2298             cur = call->jointCaps;
2299             while(cur->next) cur = cur->next;
2300             cur->next = epCap;
2301          }
2302
2303       }     
2304    }
2305
2306    return OO_OK;
2307 }
2308
2309 const char* ooGetCapTypeText (OOCapabilities cap)
2310 {
2311    static const char *capTypes[]={
2312       "unknown",
2313       "OO_NONSTANDARD",
2314       "OO_G711ALAW64K",
2315       "OO_G711ALAW56K",
2316       "OO_G711ULAW64K",
2317       "OO_G711ULAW56K",
2318       "OO_G72264K",
2319       "OO_G72256K",
2320       "OO_G72248K",
2321       "OO_G7231",
2322       "OO_G728",
2323       "OO_G729",
2324       "OO_G729ANNEXA",
2325       "OO_IS11172AUDIO",
2326       "OO_IS13818AUDIO",
2327       "OO_G729WANNEXB",
2328       "OO_G729ANNEXAWANNEXB",
2329       "OO_G7231ANNEXC",
2330       "OO_GSMFULLRATE",
2331       "OO_GSMHALFRATE",
2332       "OO_GSMENHANCEDFULLRATE",
2333       "OO_GENERICAUDIO",
2334       "OO_G729EXTENSIONS",
2335       "OO_VBD",
2336       "OO_AUDIOTELEPHONYEVENT",
2337       "OO_AUDIOTONE",
2338       "OO_EXTELEM1",
2339       "OO_VIDEO_BASE",
2340       "OO_NONSTDVIDEO",
2341       "OO_H261VIDEO",
2342       "OO_H262VIDEO",
2343       "OO_H263VIDEO",
2344       "OO_IS11172VIDEO",  /* mpeg */
2345       "OO_GENERICVIDEO",
2346       "OO_EXTELEMVIDEO"
2347    };
2348    return ooUtilsGetText (cap, capTypes, OONUMBEROF(capTypes));
2349 }