Merge "res_rtp_asterisk.c: Fix rtp source address learning for broken clients"
[asterisk/asterisk.git] / addons / ooh323c / src / ooCalls.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
17 #include "asterisk.h"
18 #include "asterisk/lock.h"
19 #include "asterisk/utils.h"
20
21 #include "ootrace.h"
22 #include "ootypes.h"
23 #include "ooCalls.h"
24 #include "ooUtils.h"
25 #include "ooports.h"
26 #include "oochannels.h"
27 #include "ooh245.h"
28 #include "ooCapability.h"
29 #include "ooGkClient.h"
30 #include "ooh323ep.h"
31 #include "ooCalls.h"
32 #include "ooCmdChannel.h"
33
34 /** Global endpoint structure */
35 extern OOH323EndPoint gH323ep;
36 extern ast_mutex_t callListLock;
37 extern ast_mutex_t newCallLock;
38
39 OOH323CallData* ooCreateCall(char* type, char*callToken)
40 {
41    OOH323CallData *call=NULL;
42    OOCTXT *pctxt=NULL;
43    OOCTXT *msgctxt=NULL;
44
45    pctxt = newContext();
46    if(!pctxt)
47    {
48       OOTRACEERR1("ERROR:Failed to create OOCTXT for new call\n");
49       return NULL;
50    }
51    msgctxt = newContext();
52    if(!msgctxt)
53    {
54       OOTRACEERR1("ERROR:Failed to create OOCTXT for new call\n");
55       return NULL;
56    }
57    ast_mutex_lock(&newCallLock);
58    /* call = (OOH323CallData*)memAlloc(&gH323ep.ctxt, sizeof(OOH323CallData));  */
59    call = (OOH323CallData*)memAlloc(pctxt, sizeof(OOH323CallData));
60    ast_mutex_unlock(&newCallLock);
61    if(!call)
62    {
63       OOTRACEERR1("ERROR:Memory - ooCreateCall - call\n");
64       return NULL;
65    } 
66    memset(call, 0, sizeof(OOH323CallData));
67    ast_cond_init(&call->gkWait, NULL);
68    ast_mutex_init(&call->GkLock);
69    ast_mutex_init(&call->Lock);
70    call->pctxt = pctxt;
71    call->msgctxt = msgctxt;
72    call->callMode = gH323ep.callMode;
73    sprintf(call->callToken, "%s", callToken);
74    sprintf(call->callType, "%s", type);
75    call->callReference = 0;
76    if(gH323ep.callerid) {
77      strncpy(call->ourCallerId, gH323ep.callerid, sizeof(call->ourCallerId)-1);
78      call->ourCallerId[sizeof(call->ourCallerId)-1] = '\0';
79    }
80    else {
81       call->ourCallerId[0] = '\0';
82    }
83    
84    memset(&call->callIdentifier, 0, sizeof(H225CallIdentifier));
85    memset(&call->confIdentifier, 0, sizeof(H225ConferenceIdentifier));
86
87    call->flags = 0;
88    if (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
89       OO_SETFLAG (call->flags, OO_M_TUNNELING);
90
91    if(gH323ep.gkClient)
92    {
93       if(OO_TESTFLAG(gH323ep.flags, OO_M_GKROUTED))
94       {
95          OO_SETFLAG(call->flags, OO_M_GKROUTED);
96       }
97    }
98
99    if (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART))
100       OO_SETFLAG (call->flags, OO_M_FASTSTART);
101
102    if (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN))
103       OO_SETFLAG (call->flags, OO_M_MEDIAWAITFORCONN);
104
105    call->fsSent = FALSE;
106
107 // May 20090713. Fix it for Video session
108
109    OO_SETFLAG(call->flags, OO_M_AUDIOSESSION);
110    
111    call->callState = OO_CALL_CREATED;
112    call->callEndReason = OO_REASON_UNKNOWN;
113    call->pCallFwdData = NULL;
114
115    if(!strcmp(call->callType, "incoming"))
116    {
117       call->callingPartyNumber = NULL;
118    }
119    else{      
120       if(ooUtilsIsStrEmpty(gH323ep.callingPartyNumber))
121       {
122          call->callingPartyNumber = NULL;
123       }
124       else{
125          call->callingPartyNumber = (char*) memAlloc(call->pctxt, 
126                                          strlen(gH323ep.callingPartyNumber)+1);
127          if(call->callingPartyNumber)
128          {
129             strcpy(call->callingPartyNumber, gH323ep.callingPartyNumber);
130          }
131          else{
132             OOTRACEERR3("Error:Memory - ooCreateCall - callingPartyNumber"
133                         ".(%s, %s)\n", call->callType, call->callToken);
134             freeContext(pctxt);
135             return NULL;
136          }
137       }
138    }
139
140    call->calledPartyNumber = NULL;
141    call->h245ConnectionAttempts = 0;
142    call->h245SessionState = OO_H245SESSION_IDLE;
143    call->dtmfmode = gH323ep.dtmfmode;
144    call->mediaInfo = NULL;
145    strcpy(call->localIP, gH323ep.signallingIP);
146    call->pH225Channel = NULL;
147    call->pH245Channel = NULL;
148    call->h245listener = NULL;
149    call->h245listenport = NULL;
150    call->remoteIP[0] = '\0';
151    call->remotePort = 0;
152    call->remoteH245Port = 0;
153    call->remoteDisplayName = NULL;
154    call->remoteAliases = NULL;
155    call->ourAliases = NULL;
156    call->masterSlaveState = OO_MasterSlave_Idle;
157    call->statusDeterminationNumber = 0;
158    call->localTermCapState = OO_LocalTermCapExchange_Idle;
159    call->remoteTermCapState = OO_RemoteTermCapExchange_Idle; 
160    call->ourCaps = NULL;
161    call->remoteCaps = NULL;
162    call->jointCaps = NULL;
163    dListInit(&call->remoteFastStartOLCs);
164    call->remoteTermCapSeqNo =0;
165    call->localTermCapSeqNo = 0;
166    memcpy(&call->capPrefs, &gH323ep.capPrefs, sizeof(OOCapPrefs));    
167    call->logicalChans = NULL;
168    call->noOfLogicalChannels = 0;
169    call->logicalChanNoBase = 1001;
170    call->logicalChanNoMax = 1100;
171    call->logicalChanNoCur = 1001;
172    call->nextSessionID = 4; /* 1,2,3 are reserved for audio, video and data */
173    dListInit(&call->timerList);
174    call->msdRetries = 0;
175    call->pFastStartRes = NULL;
176    call->usrData = NULL;
177    ooCreateCallCmdConnection(call);
178    OOTRACEINFO3("Created a new call (%s, %s)\n", call->callType, 
179                  call->callToken);
180    /* Add new call to calllist */
181    ooAddCallToList (call);
182    if(gH323ep.h323Callbacks.onNewCallCreated)
183      gH323ep.h323Callbacks.onNewCallCreated(call);
184    return call;
185 }
186
187 int ooAddCallToList(OOH323CallData *call)
188 {
189    ast_mutex_lock(&callListLock);
190
191    if(!gH323ep.callList)
192    {
193       gH323ep.callList = call;
194       call->next = NULL;
195       call->prev = NULL;
196    }
197    else{
198       call->next = gH323ep.callList;
199       call->prev = NULL;
200       gH323ep.callList->prev = call;
201       gH323ep.callList = call;
202    }
203
204    ast_mutex_unlock(&callListLock);
205
206    return OO_OK;
207 }
208
209
210 int ooEndCall(OOH323CallData *call)
211 {
212    OOTRACEDBGA4("In ooEndCall call state is - %s (%s, %s)\n", 
213                  ooGetCallStateText(call->callState), call->callType, 
214                  call->callToken);
215
216    if(call->callState == OO_CALL_REMOVED) {
217       OOTRACEINFO2("Call already removed %s\n",
218                     call->callToken);
219      return OO_OK;
220    }
221
222    if (call->callIdentifier.guid.numocts == 0) call->callState = OO_CALL_CLEARED;
223
224    if(!call->pH225Channel || call->pH225Channel->sock ==0)
225    {
226       call->callState = OO_CALL_CLEARED;
227    }
228
229    if(call->callState == OO_CALL_CLEARED || ((strcmp(call->callType, "incoming")) &&
230      call->callState == OO_CALL_CLEAR_RELEASESENT))
231    {
232       ooCleanCall(call); 
233       call->callState = OO_CALL_REMOVED;
234       return OO_OK;
235    }
236
237    if(call->logicalChans)
238    {
239       OOTRACEINFO3("Clearing all logical channels. (%s, %s)\n", call->callType,
240                     call->callToken);
241       ooClearAllLogicalChannels(call);
242    }
243
244    if(!OO_TESTFLAG(call->flags, OO_M_ENDSESSION_BUILT))
245    {
246       if(call->h245SessionState == OO_H245SESSION_ACTIVE ||
247          call->h245SessionState == OO_H245SESSION_ENDRECVD)
248       {
249          ooSendEndSessionCommand(call);
250          OO_SETFLAG(call->flags, OO_M_ENDSESSION_BUILT);
251       }
252    }
253
254
255    if(!OO_TESTFLAG(call->flags, OO_M_RELEASE_BUILT))   
256    {
257      if(call->callState == OO_CALL_CLEAR || 
258         call->callState == OO_CALL_CLEAR_RELEASERECVD)
259      {
260         ooSendReleaseComplete(call);
261         OO_SETFLAG(call->flags, OO_M_RELEASE_BUILT);
262      }
263    }
264       
265    return OO_OK;
266 }
267
268
269
270 int ooRemoveCallFromList (OOH323CallData *call)
271 {
272    if(!call || !gH323ep.callList)
273       return OO_OK;
274
275    ast_mutex_lock(&callListLock);
276
277    OOTRACEINFO3("Removing call %lx: %s\n", call, call->callToken);
278
279    if(call == gH323ep.callList)
280    {
281       if(!call->next)
282          gH323ep.callList = NULL;
283       else{
284          call->next->prev = NULL;
285          gH323ep.callList = call->next;
286       }
287    }
288    else{
289       call->prev->next = call->next;
290       if(call->next)
291          call->next->prev = call->prev;
292    }
293
294    ast_mutex_unlock(&callListLock);
295
296    return OO_OK;
297 }
298
299 int ooCleanCall(OOH323CallData *call)
300 {
301    OOCTXT *pctxt;
302
303    OOTRACEWARN4 ("Cleaning Call (%s, %s)- reason:%s\n", 
304                  call->callType, call->callToken, 
305                  ooGetReasonCodeText (call->callEndReason));
306
307    /* First clean all the logical channels, if not already cleaned. */
308    if(call->logicalChans)
309       ooClearAllLogicalChannels(call);
310
311    /* Close H.245 connection, if not already closed */
312    if(call->h245SessionState != OO_H245SESSION_CLOSED)
313       ooCloseH245Connection(call);
314    else{
315       if(call->pH245Channel && call->pH245Channel->outQueue.count > 0)
316       {
317          dListFreeAll(call->pctxt, &(call->pH245Channel->outQueue));
318          memFreePtr(call->pctxt, call->pH245Channel);
319       }
320    }
321
322    /* Close H.245 listener, if not already closed */
323    if(call->h245listener)
324    {
325       ooCloseH245Listener(call);
326    }
327    
328    /* Close H225 connection, if not already closed. */
329    if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
330    {
331       ooCloseH225Connection(call);
332    }
333
334    /* Clean timers */
335    if(call->timerList.count > 0)
336    {
337       dListFreeAll(call->pctxt, &(call->timerList));
338    }
339
340    if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
341    {
342       ooGkClientCleanCall(gH323ep.gkClient, call);
343    }
344
345    ooRemoveCallFromList (call);
346    OOTRACEINFO3("Removed call (%s, %s) from list\n", call->callType, 
347                  call->callToken);
348
349    if(call->pCallFwdData && call->pCallFwdData->fwdedByRemote)
350    {
351
352       if(gH323ep.h323Callbacks.onCallForwarded)
353          gH323ep.h323Callbacks.onCallForwarded(call);
354
355       if(ooH323HandleCallFwdRequest(call)!= OO_OK)
356       {
357          OOTRACEERR3("Error:Failed to forward call (%s, %s)\n", call->callType,
358                      call->callToken);
359       }
360    }
361    else {
362       if(gH323ep.h323Callbacks.onCallCleared)
363          gH323ep.h323Callbacks.onCallCleared(call);
364    }
365
366    if (call->rtpMask) {
367         ast_mutex_lock(&call->rtpMask->lock);
368         call->rtpMask->inuse--;
369         ast_mutex_unlock(&call->rtpMask->lock);
370         if ((call->rtpMask->inuse) == 0) {
371                 regfree(&call->rtpMask->regex);
372                 ast_mutex_destroy(&call->rtpMask->lock);
373                 ast_free(call->rtpMask);
374         }
375    }
376
377    if ((pctxt = call->msgctxt) != NULL) {
378         freeContext(pctxt);
379         ast_free(pctxt);
380         call->msgctxt = NULL;
381    }
382 /* May !!!! Fix it !! */
383    /* free(pctxt); */
384
385    return OO_OK;
386 }
387
388
389 int ooCallSetCallerId(OOH323CallData* call, const char* callerid)
390 {
391    if(!call || !callerid) return OO_FAILED;
392    strncpy(call->ourCallerId, callerid, sizeof(call->ourCallerId)-1);
393    call->ourCallerId[sizeof(call->ourCallerId)-1]='\0';
394    return OO_OK;
395 }
396
397 int ooCallSetCallingPartyNumber(OOH323CallData *call, const char *number)
398 {
399    if(call->callingPartyNumber) 
400       memFreePtr(call->pctxt, call->callingPartyNumber);
401
402    call->callingPartyNumber = (char*) memAlloc(call->pctxt, strlen(number)+1);
403    if(call->callingPartyNumber)
404    {
405      strcpy(call->callingPartyNumber, number);
406    }
407    else{
408       OOTRACEERR3("Error:Memory - ooCallSetCallingPartyNumber - "
409                   "callingPartyNumber.(%s, %s)\n", call->callType, 
410                   call->callToken);
411       return OO_FAILED;
412    }
413    /* Set dialed digits alias */
414    /*   if(!strcmp(call->callType, "outgoing"))
415    {
416       ooCallAddAliasDialedDigits(call, number);
417    }*/
418    return OO_OK;
419 }
420
421 int ooCallGetCallingPartyNumber(OOH323CallData *call, char *buffer, int len)
422 {
423    if(call->callingPartyNumber)
424    {
425       if(len>(int)strlen(call->callingPartyNumber))
426       {
427          strcpy(buffer, call->callingPartyNumber);
428          return OO_OK;
429       }
430    }
431    
432    return OO_FAILED;
433 }
434
435
436 int ooCallSetCalledPartyNumber(OOH323CallData *call, const char *number)
437 {
438    if(call->calledPartyNumber) 
439       memFreePtr(call->pctxt, call->calledPartyNumber);
440
441    call->calledPartyNumber = (char*) memAlloc(call->pctxt, strlen(number)+1);
442    if(call->calledPartyNumber)
443    {
444      strcpy(call->calledPartyNumber, number);
445    }
446    else{
447       OOTRACEERR3("Error:Memory - ooCallSetCalledPartyNumber - "
448                   "calledPartyNumber.(%s, %s)\n", call->callType, 
449                   call->callToken);
450       return OO_FAILED;
451    }
452    return OO_OK;
453 }
454
455 int ooCallGetCalledPartyNumber(OOH323CallData *call, char *buffer, int len)
456 {
457    if(call->calledPartyNumber)
458    {
459       if(len>(int)strlen(call->calledPartyNumber))
460       {
461          strcpy(buffer, call->calledPartyNumber);
462          return OO_OK;
463       }
464    }
465    
466    return OO_FAILED;
467 }
468
469 int ooCallClearAliases(OOH323CallData *call)
470 {
471    if(call->ourAliases)
472       memFreePtr(call->pctxt, call->ourAliases);
473    call->ourAliases = NULL;
474    return OO_OK;
475 }
476
477
478 int ooCallAddAlias
479    (OOH323CallData *call, int aliasType, const char *value, OOBOOL local)
480 {
481    ooAliases * psNewAlias=NULL;
482    psNewAlias = (ooAliases*)memAlloc(call->pctxt, sizeof(ooAliases));
483    if(!psNewAlias)
484    {
485       OOTRACEERR3("Error:Memory - ooCallAddAlias - psNewAlias"
486                   "(%s, %s)\n", call->callType, call->callToken);
487       return OO_FAILED;
488    }
489    psNewAlias->type = aliasType;
490    psNewAlias->value = (char*) memAlloc(call->pctxt, strlen(value)+1);
491    if(!psNewAlias->value)
492    {
493       OOTRACEERR3("Error:Memory - ooCallAddAlias - psNewAlias->value"
494                   " (%s, %s)\n", call->callType, call->callToken);
495       memFreePtr(call->pctxt, psNewAlias);
496       return OO_FAILED;
497    }
498    strcpy(psNewAlias->value, value);
499
500    if(local)
501    {
502       psNewAlias->next = call->ourAliases;
503       call->ourAliases = psNewAlias;
504    }
505    else {
506      psNewAlias->next = call->remoteAliases;
507      call->remoteAliases = psNewAlias;
508    }
509
510    OOTRACEDBGC5("Added %s alias %s to call. (%s, %s)\n", 
511               local?"local":"remote", value, call->callType, call->callToken);
512    return OO_OK;
513 }
514
515 int ooCallAddAliasH323ID(OOH323CallData *call, const char* h323id)
516 {
517    return ooCallAddAlias(call, T_H225AliasAddress_h323_ID, h323id, TRUE);
518 }
519
520
521 int ooCallAddAliasDialedDigits(OOH323CallData *call, const char* dialedDigits)
522 {
523    return ooCallAddAlias
524                (call, T_H225AliasAddress_dialedDigits, dialedDigits, TRUE);
525 }
526
527
528 int ooCallAddAliasEmailID(OOH323CallData *call, const char* email)
529 {
530    return ooCallAddAlias(call, T_H225AliasAddress_email_ID, email, TRUE);
531 }
532
533
534 int ooCallAddAliasURLID(OOH323CallData *call, const char* url)
535 {
536    return ooCallAddAlias(call, T_H225AliasAddress_url_ID, url, TRUE);
537
538  
539
540 int ooCallAddRemoteAliasH323ID(OOH323CallData *call, const char* h323id)
541 {
542    return ooCallAddAlias(call, T_H225AliasAddress_h323_ID, h323id, FALSE);
543 }
544
545 int ooCallAddRemoteAliasDialedDigits
546    (OOH323CallData *call, const char* dialedDigits)
547 {
548    return ooCallAddAlias
549               (call, T_H225AliasAddress_dialedDigits, dialedDigits, FALSE);
550 }
551
552
553
554 /* Used to override global end point capabilities and add call specific 
555    capabilities */
556
557 int ooCallAddG726Capability(OOH323CallData *call, int cap, int txframes, 
558                             int rxframes, OOBOOL silenceSuppression, int dir,
559                             cb_StartReceiveChannel startReceiveChannel,
560                             cb_StartTransmitChannel startTransmitChannel,
561                             cb_StopReceiveChannel stopReceiveChannel,
562                             cb_StopTransmitChannel stopTransmitChannel)
563 {
564    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
565                                 silenceSuppression, dir, startReceiveChannel, 
566                                 startTransmitChannel, stopReceiveChannel, 
567                                 stopTransmitChannel, FALSE);
568 }
569 int ooCallAddAMRNBCapability(OOH323CallData *call, int cap, int txframes, 
570                             int rxframes, OOBOOL silenceSuppression, int dir,
571                             cb_StartReceiveChannel startReceiveChannel,
572                             cb_StartTransmitChannel startTransmitChannel,
573                             cb_StopReceiveChannel stopReceiveChannel,
574                             cb_StopTransmitChannel stopTransmitChannel)
575 {
576    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
577                                 silenceSuppression, dir, startReceiveChannel, 
578                                 startTransmitChannel, stopReceiveChannel, 
579                                 stopTransmitChannel, FALSE);
580 }
581
582 int ooCallAddSpeexCapability(OOH323CallData *call, int cap, int txframes, 
583                             int rxframes, OOBOOL silenceSuppression, int dir,
584                             cb_StartReceiveChannel startReceiveChannel,
585                             cb_StartTransmitChannel startTransmitChannel,
586                             cb_StopReceiveChannel stopReceiveChannel,
587                             cb_StopTransmitChannel stopTransmitChannel)
588 {
589    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
590                                 silenceSuppression, dir, startReceiveChannel, 
591                                 startTransmitChannel, stopReceiveChannel, 
592                                 stopTransmitChannel, FALSE);
593 }
594
595 int ooCallAddG7231Capability(OOH323CallData *call, int cap, int txframes, 
596                             int rxframes, OOBOOL silenceSuppression, int dir,
597                             cb_StartReceiveChannel startReceiveChannel,
598                             cb_StartTransmitChannel startTransmitChannel,
599                             cb_StopReceiveChannel stopReceiveChannel,
600                             cb_StopTransmitChannel stopTransmitChannel)
601 {
602    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, 
603                                 silenceSuppression, dir, startReceiveChannel, 
604                                 startTransmitChannel, stopReceiveChannel, 
605                                 stopTransmitChannel, FALSE);
606 }
607
608
609
610 int ooCallAddG729Capability(OOH323CallData *call, int cap, int txframes, 
611                             int rxframes, int dir,
612                             cb_StartReceiveChannel startReceiveChannel,
613                             cb_StartTransmitChannel startTransmitChannel,
614                             cb_StopReceiveChannel stopReceiveChannel,
615                             cb_StopTransmitChannel stopTransmitChannel)
616 {
617    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
618                           dir, startReceiveChannel, startTransmitChannel, 
619                           stopReceiveChannel, stopTransmitChannel, FALSE);
620 }
621
622 /*
623 int ooCallAddG726Capability(OOH323CallData *call, int cap, int txframes, 
624                             int rxframes, int dir,
625                             cb_StartReceiveChannel startReceiveChannel,
626                             cb_StartTransmitChannel startTransmitChannel,
627                             cb_StopReceiveChannel stopReceiveChannel,
628                             cb_StopTransmitChannel stopTransmitChannel)
629 {
630    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
631                           dir, startReceiveChannel, startTransmitChannel, 
632                           stopReceiveChannel, stopTransmitChannel, FALSE);
633 }
634 */
635
636 int ooCallAddG728Capability(OOH323CallData *call, int cap, int txframes, 
637                             int rxframes, int dir,
638                             cb_StartReceiveChannel startReceiveChannel,
639                             cb_StartTransmitChannel startTransmitChannel,
640                             cb_StopReceiveChannel stopReceiveChannel,
641                             cb_StopTransmitChannel stopTransmitChannel)
642 {
643    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
644                           dir, startReceiveChannel, startTransmitChannel, 
645                           stopReceiveChannel, stopTransmitChannel, FALSE);
646 }
647
648 int ooCallAddG711Capability(OOH323CallData *call, int cap, int txframes, 
649                             int rxframes, int dir,
650                             cb_StartReceiveChannel startReceiveChannel,
651                             cb_StartTransmitChannel startTransmitChannel,
652                             cb_StopReceiveChannel stopReceiveChannel,
653                             cb_StopTransmitChannel stopTransmitChannel)
654 {
655    return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, FALSE,
656                             dir, startReceiveChannel, startTransmitChannel, 
657                             stopReceiveChannel, stopTransmitChannel, FALSE);
658 }
659
660 int ooCallAddGSMCapability
661    (OOH323CallData* call, int cap, ASN1USINT framesPerPkt, 
662     OOBOOL comfortNoise, OOBOOL scrambled, int dir,
663     cb_StartReceiveChannel startReceiveChannel,
664     cb_StartTransmitChannel startTransmitChannel,
665     cb_StopReceiveChannel stopReceiveChannel,
666     cb_StopTransmitChannel stopTransmitChannel)
667 {
668    return ooCapabilityAddGSMCapability(call, cap, framesPerPkt, comfortNoise, 
669                                      scrambled, dir, startReceiveChannel, 
670                                      startTransmitChannel, stopReceiveChannel,
671                                      stopTransmitChannel, FALSE);
672 }
673
674
675 int ooCallAddH263VideoCapability
676    (OOH323CallData *call, int cap, unsigned sqcifMPI, unsigned qcifMPI, 
677     unsigned cifMPI, unsigned cif4MPI, unsigned cif16MPI, unsigned maxBitRate, 
678     int dir, cb_StartReceiveChannel startReceiveChannel,
679     cb_StartTransmitChannel startTransmitChannel,
680     cb_StopReceiveChannel stopReceiveChannel,
681     cb_StopTransmitChannel stopTransmitChannel)
682 {
683
684    return ooCapabilityAddH263VideoCapability(call, sqcifMPI, qcifMPI, cifMPI,
685                                      cif4MPI, cif16MPI, maxBitRate,dir,
686                                      startReceiveChannel, startTransmitChannel,
687                                      stopReceiveChannel, stopTransmitChannel, 
688                                      FALSE);
689
690 }
691
692 int ooCallEnableDTMFRFC2833(OOH323CallData *call, int dynamicRTPPayloadType)
693 {
694    return ooCapabilityEnableDTMFRFC2833(call, dynamicRTPPayloadType);
695 }
696
697 int ooCallDisableDTMFRFC2833(OOH323CallData *call)
698 {
699   return ooCapabilityDisableDTMFRFC2833(call);
700 }
701
702 int ooCallEnableDTMFCISCO(OOH323CallData *call, int dynamicRTPPayloadType)
703 {
704    return ooCapabilityEnableDTMFCISCO(call, dynamicRTPPayloadType);
705 }
706
707 int ooCallDisableDTMFCISCO(OOH323CallData *call)
708 {
709   return ooCapabilityDisableDTMFCISCO(call);
710 }
711
712
713 int ooCallEnableDTMFH245Alphanumeric(OOH323CallData *call)
714 {
715    return ooCapabilityEnableDTMFH245Alphanumeric(call);
716 }
717
718 int ooCallDisableDTMFH245Alphanumeric(OOH323CallData *call)
719 {
720    return ooCapabilityDisableDTMFH245Alphanumeric(call);
721 }
722
723 int ooCallEnableDTMFH245Signal(OOH323CallData *call)
724 {
725    return ooCapabilityEnableDTMFH245Signal(call);
726 }
727
728 int ooCallDisableDTMFH245Signal(OOH323CallData *call)
729 {
730    return ooCapabilityDisableDTMFH245Signal(call);
731 }
732
733 int ooCallEnableDTMFQ931Keypad(OOH323CallData *call)
734 {
735    return ooCapabilityEnableDTMFQ931Keypad(call);
736 }
737
738 int ooCallDisableDTMFQ931Keypad(OOH323CallData *call)
739 {
740    return ooCapabilityDisableDTMFQ931Keypad(call);
741 }
742
743
744 OOH323CallData* ooFindCallByToken(const char *callToken)
745 {
746    OOH323CallData *call;
747    if(!callToken)
748    {
749       OOTRACEERR1("ERROR:Invalid call token passed - ooFindCallByToken\n");
750       return NULL;
751    }
752
753    ast_mutex_lock(&callListLock);
754
755    if(!gH323ep.callList)
756    {
757       OOTRACEERR1("ERROR: Empty calllist - ooFindCallByToken failed\n");
758       ast_mutex_unlock(&callListLock);
759       return NULL;
760    }
761    call = gH323ep.callList;
762    while(call)
763    {
764       if(!strcmp(call->callToken, callToken))
765          break;
766       else
767          call = call->next;
768    }
769    
770    if(!call)
771    {
772       OOTRACEERR2("ERROR:Call with token %s not found\n", callToken);
773       ast_mutex_unlock(&callListLock);
774       return NULL;
775    }
776
777    ast_mutex_unlock(&callListLock);
778
779    OOTRACEINFO3("INFO: FinCall returned %lx for call: %s\n", call, callToken);
780
781    return call;
782 }
783
784
785
786 /* Checks whether session with suplied ID and direction is already active*/
787 ASN1BOOL ooIsSessionEstablished(OOH323CallData *call, int sessionID, char* dir)
788 {
789    OOLogicalChannel * temp = NULL;
790    temp = call->logicalChans;
791    while(temp)
792    {
793       if(temp->sessionID == sessionID              &&
794          temp->state == OO_LOGICALCHAN_ESTABLISHED && 
795          !strcmp(temp->dir, dir)                     )
796          return TRUE;
797       temp = temp->next;
798    }
799    return FALSE;
800 }
801
802 int ooAddMediaInfo(OOH323CallData *call, OOMediaInfo mediaInfo)
803 {
804    OOMediaInfo *newMediaInfo=NULL;
805
806    if(!call)
807    {
808       OOTRACEERR3("Error:Invalid 'call' param for ooAddMediaInfo.(%s, %s)\n",
809                    call->callType, call->callToken);
810       return OO_FAILED;
811    }
812    newMediaInfo = (OOMediaInfo*) memAlloc(call->pctxt, sizeof(OOMediaInfo));
813    if(!newMediaInfo)
814    {
815       OOTRACEERR3("Error:Memory - ooAddMediaInfo - newMediaInfo. "
816                   "(%s, %s)\n", call->callType, call->callToken);
817       return OO_FAILED;
818    }
819
820    memcpy (newMediaInfo, &mediaInfo, sizeof(OOMediaInfo));
821
822    OOTRACEDBGC4("Configured mediainfo for cap %s (%s, %s)\n", 
823                 ooGetCapTypeText(mediaInfo.cap),
824                 call->callType, call->callToken);
825    if(!call->mediaInfo) {
826       newMediaInfo->next = NULL;
827       call->mediaInfo = newMediaInfo;
828    }
829    else {
830       newMediaInfo->next = call->mediaInfo;
831       call->mediaInfo = newMediaInfo;
832    }
833    return OO_OK;
834 }
835
836 unsigned ooCallGenerateSessionID
837    (OOH323CallData *call, OOCapType type, char *dir)
838 {
839    unsigned sessionID=0;
840
841    if(type == OO_CAP_TYPE_AUDIO)
842    {
843       if(!ooGetLogicalChannel(call, 1, dir))
844       {
845          sessionID = 1;
846       }
847       else{
848          if(call->masterSlaveState == OO_MasterSlave_Master)
849             sessionID = call->nextSessionID++;
850          else{
851             OOTRACEDBGC4("Session id for %s channel of type audio has to be "
852                         "provided by remote.(%s, %s)\n", dir, call->callType, 
853                          call->callToken);
854             sessionID = 0; /* Will be assigned by remote */
855          }
856       }
857    }
858
859    if(type == OO_CAP_TYPE_VIDEO)
860    {
861       if(!ooGetLogicalChannel(call, 2, dir))
862       {
863          sessionID = 2;
864       }
865       else{
866          if(call->masterSlaveState == OO_MasterSlave_Master)
867             sessionID = call->nextSessionID++;
868          else{
869             sessionID = 0; /* Will be assigned by remote */
870             OOTRACEDBGC4("Session id for %s channel of type video has to be "
871                         "provided by remote.(%s, %s)\n", dir, call->callType, 
872                          call->callToken);
873          }
874       }
875    }
876    if(type == OO_CAP_TYPE_DATA)
877    {
878       if(!ooGetLogicalChannel(call, 3, dir))
879       {
880          sessionID = 3;
881       }
882       else{
883          if(call->masterSlaveState == OO_MasterSlave_Master)
884             sessionID = call->nextSessionID++;
885          else{
886             sessionID = 0; /* Will be assigned by remote */
887             OOTRACEDBGC4("Session id for %s channel of type data has to be "
888                         "provided by remote.(%s, %s)\n", dir, call->callType, 
889                          call->callToken);
890          }
891       }
892    }
893    return sessionID;
894
895 }
896
897
898 int ooCallH245ConnectionRetryTimerExpired(void *data)
899 {
900    ooTimerCallback *cbData = (ooTimerCallback*) data;
901    OOH323CallData *call = cbData->call;
902
903    OOTRACEINFO3("H245 connection retry timer expired. (%s, %s)\n", 
904                                             call->callType, call->callToken); 
905    memFreePtr(call->pctxt, cbData);
906
907    call->h245ConnectionAttempts++;
908
909    ooCreateH245Connection(call);
910
911    return OO_OK;
912 }
913
914 const char* ooGetReasonCodeText (OOUINT32 code)
915 {
916    static const char* reasonCodeText[] = {
917       "OO_REASON_UNKNOWN", 
918       "OO_REASON_INVALIDMESSAGE",
919       "OO_REASON_TRANSPORTFAILURE", 
920       "OO_REASON_NOROUTE",
921       "OO_REASON_NOUSER",
922       "OO_REASON_NOBW",
923       "OO_REASON_GK_NOCALLEDUSER",
924       "OO_REASON_GK_NOCALLERUSER",
925       "OO_REASON_GK_NORESOURCES",
926       "OO_REASON_GK_UNREACHABLE",
927       "OO_REASON_GK_CLEARED",
928       "OO_REASON_NOCOMMON_CAPABILITIES",
929       "OO_REASON_REMOTE_FWDED",   
930       "OO_REASON_LOCAL_FWDED",
931       "OO_REASON_REMOTE_CLEARED", 
932       "OO_REASON_LOCAL_CLEARED", 
933       "OO_REASON_REMOTE_BUSY",
934       "OO_REASON_LOCAL_BUSY",
935       "OO_REASON_REMOTE_NOANSWER",
936       "OO_REASON_LOCAL_NOTANSWERED",
937       "OO_REASON_REMOTE_REJECTED",
938       "OO_REASON_LOCAL_REJECTED",
939       "OO_REASON_REMOTE_CONGESTED",
940       "OO_REASON_LOCAL_CONGESTED"
941    };
942    return ooUtilsGetText (code, reasonCodeText, OONUMBEROF(reasonCodeText));
943 }
944
945 const char* ooGetCallStateText (OOCallState callState)
946 {
947    static const char* callStateText[] = {
948       "OO_CALL_CREATED",
949       "OO_CALL_WAITING_ADMISSION",
950       "OO_CALL_CONNECTING",
951       "OO_CALL_CONNECTED",
952       "OO_CALL_PAUSED",
953       "OO_CALL_CLEAR",
954       "OO_CALL_CLEAR_RELEASERECVD",
955       "OO_CALL_CLEAR_RELEASESENT",
956       "OO_CALL_CLEARED"
957    };
958    return ooUtilsGetText (callState, callStateText, OONUMBEROF(callStateText));
959 }
960