Fix use freed pointer in return value from call thread
[asterisk/asterisk.git] / addons / ooh323cDriver.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 "ooh323cDriver.h"
18
19 #include "asterisk.h"
20 #include "asterisk/lock.h"
21
22 #include "asterisk/pbx.h"
23 #include "asterisk/logger.h"
24
25 #undef AST_BACKGROUND_STACKSIZE
26 #define AST_BACKGROUND_STACKSIZE 768 * 1024
27
28 #define SEC_TO_HOLD_THREAD 24
29
30 extern struct ast_module *myself;
31 extern OOBOOL gH323Debug;
32 extern OOH323EndPoint gH323ep;
33 /* ooh323c stack thread. */
34 static pthread_t ooh323c_thread = AST_PTHREADT_NULL;
35 static pthread_t ooh323cmd_thread = AST_PTHREADT_NULL;
36 static int grxframes = 240;
37
38 static int gtxframes = 20;
39
40 static struct callthread {
41         ast_mutex_t             lock;
42         int                     thePipe[2];
43         OOBOOL                  inUse;
44         ooCallData*             call;
45         struct callthread       *next, *prev;
46 } *callThreads = NULL;
47
48 AST_MUTEX_DEFINE_STATIC(callThreadsLock);
49
50
51 int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel);
52 int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel);
53 int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel);
54 int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel);
55
56 int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
57 int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
58 int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
59 int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
60
61 void* ooh323c_stack_thread(void* dummy);
62 void* ooh323c_cmd_thread(void* dummy);
63 void* ooh323c_call_thread(void* dummy);
64 int ooh323c_set_aliases(ooAliases * aliases);
65
66 void* ooh323c_stack_thread(void* dummy)
67 {
68
69   ooMonitorChannels();
70   return dummy;
71 }
72
73 void* ooh323c_cmd_thread(void* dummy)
74 {
75
76   ooMonitorCmdChannels();
77   return dummy;
78 }
79
80 void* ooh323c_call_thread(void* dummy)
81 {
82  struct callthread* mycthread = (struct callthread *)dummy;
83  struct pollfd pfds[1];
84  char c;
85  int res;
86
87  do {
88
89         ooMonitorCallChannels((ooCallData*)mycthread->call);
90         mycthread->call = NULL;
91         mycthread->prev = NULL;
92         mycthread->inUse = FALSE;
93
94         ast_mutex_lock(&callThreadsLock);
95         mycthread->next = callThreads;
96         callThreads = mycthread;
97         if (mycthread->next) mycthread->next->prev = mycthread;
98         ast_mutex_unlock(&callThreadsLock);
99
100         pfds[0].fd = mycthread->thePipe[0];
101         pfds[0].events = POLLIN;
102         ooSocketPoll(pfds, 1, SEC_TO_HOLD_THREAD * 1000);
103         if (ooPDRead(pfds, 1, mycthread->thePipe[0]))
104                 res = read(mycthread->thePipe[0], &c, 1);
105
106         ast_mutex_lock(&callThreadsLock);
107         ast_mutex_lock(&mycthread->lock);
108         if (mycthread->prev)
109                 mycthread->prev->next = mycthread->next;
110         else
111                 callThreads = mycthread->next;
112         if (mycthread->next)
113                 mycthread->next->prev = mycthread->prev;
114         ast_mutex_unlock(&mycthread->lock);
115         ast_mutex_unlock(&callThreadsLock);
116
117  } while (mycthread->call != NULL);
118
119  
120  ast_mutex_destroy(&mycthread->lock);
121
122  close(mycthread->thePipe[0]);
123  close(mycthread->thePipe[1]);
124  free(mycthread);
125  ast_module_unref(myself);
126  ast_update_use_count();
127  return NULL;
128 }
129
130 int ooh323c_start_call_thread(ooCallData *call) {
131  char c = 'c';
132  int res;
133  struct callthread *cur = callThreads;
134
135  ast_mutex_lock(&callThreadsLock);
136  while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) {
137         cur = cur->next;
138  }
139  ast_mutex_unlock(&callThreadsLock);
140
141  if (cur != NULL && cur->inUse) {
142         ast_mutex_unlock(&cur->lock);
143         cur = NULL;
144  }
145
146 /* make new thread */
147  if (cur == NULL) {
148         if (!(cur = ast_calloc(1, sizeof(struct callthread)))) {
149                 ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n",
150                                                         call->callToken);
151                 return -1;
152         }
153
154         ast_module_ref(myself);
155         if ((socketpair(PF_LOCAL, SOCK_STREAM, 0, cur->thePipe)) == -1) {
156                 ast_log(LOG_ERROR, "Can't create thread pipe for call %s\n", call->callToken);
157                 free(cur);
158                 return -1;
159         }
160         cur->inUse = TRUE;
161         cur->call = call;
162
163         ast_mutex_init(&cur->lock);
164
165         if (gH323Debug)
166                 ast_debug(1,"new call thread created for call %s\n", call->callToken);
167
168         if(ast_pthread_create_detached_background(&call->callThread, NULL, ooh323c_call_thread, cur) < 0)
169         {
170                 ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n",
171                                         call->callToken);
172                 ast_mutex_destroy(&cur->lock);
173                 close(cur->thePipe[0]);
174                 close(cur->thePipe[1]);
175                 free(cur);
176                 return -1;
177         }
178
179  } else {
180         if (gH323Debug)
181                 ast_debug(1,"using existing call thread for call %s\n", call->callToken);
182         cur->inUse = TRUE;
183         cur->call = call;
184         res = write(cur->thePipe[1], &c, 1);
185         ast_mutex_unlock(&cur->lock);
186
187  }
188  return 0;
189 }
190
191
192 int ooh323c_stop_call_thread(ooCallData *call) {
193  if (call->callThread != AST_PTHREADT_NULL) {
194   ooStopMonitorCallChannels(call);
195  }
196  return 0;
197 }
198
199 int ooh323c_start_stack_thread()
200 {
201    if(ast_pthread_create_background(&ooh323c_thread, NULL, ooh323c_stack_thread, NULL) < 0)
202    {
203       ast_log(LOG_ERROR, "Unable to start ooh323c thread.\n");
204       return -1;
205    }
206    if(ast_pthread_create_background(&ooh323cmd_thread, NULL, ooh323c_cmd_thread, NULL) < 0)
207    {
208       ast_log(LOG_ERROR, "Unable to start ooh323cmd thread.\n");
209       return -1;
210    }
211    return 0;
212 }
213
214 int ooh323c_stop_stack_thread(void)
215 {
216    if(ooh323c_thread !=  AST_PTHREADT_NULL)
217    {
218       ooStopMonitor();
219       pthread_join(ooh323c_thread, NULL);
220       ooh323c_thread =  AST_PTHREADT_NULL;
221       pthread_join(ooh323cmd_thread, NULL);
222       ooh323cmd_thread =  AST_PTHREADT_NULL;
223    }
224    return 0;
225 }
226
227 int ooh323c_set_capability
228    (struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec)
229 {
230    int ret = 0, x;
231    struct ast_format tmpfmt;
232    if(gH323Debug)
233      ast_verbose("\tAdding capabilities to H323 endpoint\n");
234    
235    for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
236    {
237       if(tmpfmt.id == AST_FORMAT_ULAW)
238       {
239          if(gH323Debug)
240             ast_verbose("\tAdding g711 ulaw capability to H323 endpoint\n");
241          ret= ooH323EpAddG711Capability(OO_G711ULAW64K, gtxframes, grxframes, 
242                                      OORXANDTX, &ooh323c_start_receive_channel,
243                                      &ooh323c_start_transmit_channel,
244                                      &ooh323c_stop_receive_channel, 
245                                      &ooh323c_stop_transmit_channel);
246       }
247       if(tmpfmt.id == AST_FORMAT_ALAW)
248       {
249          if(gH323Debug)
250             ast_verbose("\tAdding g711 alaw capability to H323 endpoint\n");
251          ret= ooH323EpAddG711Capability(OO_G711ALAW64K, gtxframes, grxframes, 
252                                      OORXANDTX, &ooh323c_start_receive_channel,
253                                      &ooh323c_start_transmit_channel,
254                                      &ooh323c_stop_receive_channel, 
255                                      &ooh323c_stop_transmit_channel);
256       }
257
258       if(tmpfmt.id == AST_FORMAT_G729A)
259       {
260          if(gH323Debug)
261             ast_verbose("\tAdding g729A capability to H323 endpoint\n");
262          ret = ooH323EpAddG729Capability(OO_G729A, 2, 24, 
263                                      OORXANDTX, &ooh323c_start_receive_channel,
264                                      &ooh323c_start_transmit_channel,
265                                      &ooh323c_stop_receive_channel, 
266                                      &ooh323c_stop_transmit_channel);
267
268          if(gH323Debug)
269             ast_verbose("\tAdding g729 capability to H323 endpoint\n");
270          ret |= ooH323EpAddG729Capability(OO_G729, 2, 24, 
271                                      OORXANDTX, &ooh323c_start_receive_channel,
272                                      &ooh323c_start_transmit_channel,
273                                      &ooh323c_stop_receive_channel, 
274                                      &ooh323c_stop_transmit_channel);
275          if(gH323Debug)
276             ast_verbose("\tAdding g729b capability to H323 endpoint\n");
277          ret |= ooH323EpAddG729Capability(OO_G729B, 2, 24, 
278                                      OORXANDTX, &ooh323c_start_receive_channel,
279                                      &ooh323c_start_transmit_channel,
280                                      &ooh323c_stop_receive_channel, 
281                                      &ooh323c_stop_transmit_channel);
282       }
283
284       if(tmpfmt.id == AST_FORMAT_G723_1)
285       {
286          if(gH323Debug)
287             ast_verbose("\tAdding g7231 capability to H323 endpoint\n");
288          ret = ooH323EpAddG7231Capability(OO_G7231, 1, 1, FALSE, 
289                                      OORXANDTX, &ooh323c_start_receive_channel,
290                                      &ooh323c_start_transmit_channel,
291                                      &ooh323c_stop_receive_channel, 
292                                      &ooh323c_stop_transmit_channel);
293
294       }
295
296       if(tmpfmt.id == AST_FORMAT_G726)
297       {
298          if(gH323Debug)
299             ast_verbose("\tAdding g726 capability to H323 endpoint\n");
300          ret = ooH323EpAddG726Capability(OO_G726, gtxframes, grxframes, FALSE, 
301                                      OORXANDTX, &ooh323c_start_receive_channel,
302                                      &ooh323c_start_transmit_channel,
303                                      &ooh323c_stop_receive_channel, 
304                                      &ooh323c_stop_transmit_channel);
305
306       }
307
308       if(tmpfmt.id == AST_FORMAT_G726_AAL2)
309       {
310          if(gH323Debug)
311             ast_verbose("\tAdding g726aal2 capability to H323 endpoint\n");
312          ret = ooH323EpAddG726Capability(OO_G726AAL2, gtxframes, grxframes, FALSE, 
313                                      OORXANDTX, &ooh323c_start_receive_channel,
314                                      &ooh323c_start_transmit_channel,
315                                      &ooh323c_stop_receive_channel, 
316                                      &ooh323c_stop_transmit_channel);
317
318       }
319
320       if(tmpfmt.id == AST_FORMAT_H263)
321       {
322          if(gH323Debug)
323             ast_verbose("\tAdding h263 capability to H323 endpoint\n");
324          ret = ooH323EpAddH263VideoCapability(OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, 
325                                      OORXANDTX, &ooh323c_start_receive_channel,
326                                      &ooh323c_start_transmit_channel,
327                                      &ooh323c_stop_receive_channel, 
328                                      &ooh323c_stop_transmit_channel);
329
330       }
331
332       if(tmpfmt.id == AST_FORMAT_GSM)
333       {
334          if(gH323Debug)
335             ast_verbose("\tAdding gsm capability to H323 endpoint\n");
336          ret = ooH323EpAddGSMCapability(OO_GSMFULLRATE, 4, FALSE, FALSE, 
337                                      OORXANDTX, &ooh323c_start_receive_channel,
338                                      &ooh323c_start_transmit_channel,
339                                      &ooh323c_stop_receive_channel, 
340                                      &ooh323c_stop_transmit_channel);
341
342       }
343       
344 #ifdef AST_FORMAT_AMRNB
345       if(tmpfmt.id == AST_FORMAT_AMRNB)
346       {
347          if(gH323Debug)
348             ast_verbose("\tAdding amr nb capability to H323 endpoint\n");
349          ret = ooH323EpAddAMRNBCapability(OO_AMRNB, 4, 4, FALSE, 
350                                      OORXANDTX, &ooh323c_start_receive_channel,
351                                      &ooh323c_start_transmit_channel,
352                                      &ooh323c_stop_receive_channel, 
353                                      &ooh323c_stop_transmit_channel);
354
355       }
356 #endif
357
358 #ifdef AST_FORMAT_SPEEX
359       if(tmpfmt.id == AST_FORMAT_SPEEX)
360       {
361          if(gH323Debug)
362             ast_verbose("\tAdding speex capability to H323 endpoint\n");
363          ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE, 
364                                      OORXANDTX, &ooh323c_start_receive_channel,
365                                      &ooh323c_start_transmit_channel,
366                                      &ooh323c_stop_receive_channel, 
367                                      &ooh323c_stop_transmit_channel);
368
369       }
370 #endif
371       
372    }
373    
374    if(dtmf & H323_DTMF_CISCO)
375       ret |= ooH323EpEnableDTMFCISCO(0);
376    if(dtmf & H323_DTMF_RFC2833)
377       ret |= ooH323EpEnableDTMFRFC2833(0);
378    else if(dtmf & H323_DTMF_H245ALPHANUMERIC)
379       ret |= ooH323EpEnableDTMFH245Alphanumeric();
380    else if(dtmf & H323_DTMF_H245SIGNAL)
381       ret |= ooH323EpEnableDTMFH245Signal();
382
383    return ret;
384 }
385
386 int ooh323c_set_capability_for_call
387    (ooCallData *call, struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
388                  int t38support, int g729onlyA)
389 {
390    int ret = 0, x, txframes;
391    struct ast_format tmpfmt;
392    if(gH323Debug)
393      ast_verbose("\tAdding capabilities to call(%s, %s)\n", call->callType, 
394                                                             call->callToken);
395    if(dtmf & H323_DTMF_CISCO || 1)
396       ret |= ooCallEnableDTMFCISCO(call,dtmfcodec);
397    if(dtmf & H323_DTMF_RFC2833 || 1)
398       ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec);
399    if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1)
400       ret |= ooCallEnableDTMFH245Alphanumeric(call);
401    if(dtmf & H323_DTMF_H245SIGNAL || 1)
402       ret |= ooCallEnableDTMFH245Signal(call);
403
404    if (t38support)
405         ooCapabilityAddT38Capability(call, OO_T38, OORXANDTX, 
406                                         &ooh323c_start_receive_datachannel,
407                                         &ooh323c_start_transmit_datachannel,
408                                         &ooh323c_stop_receive_datachannel,
409                                         &ooh323c_stop_transmit_datachannel,
410                                         0);
411
412    for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
413    {
414       if(tmpfmt.id == AST_FORMAT_ULAW)
415       {
416          if(gH323Debug)
417             ast_verbose("\tAdding g711 ulaw capability to call(%s, %s)\n", 
418                                               call->callType, call->callToken);
419          txframes = prefs->framing[x];
420          ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes, 
421                                       txframes, OORXANDTX, 
422                                       &ooh323c_start_receive_channel,
423                                       &ooh323c_start_transmit_channel,
424                                       &ooh323c_stop_receive_channel, 
425                                       &ooh323c_stop_transmit_channel);
426       }
427       if(tmpfmt.id == AST_FORMAT_ALAW)
428       {
429          if(gH323Debug)
430             ast_verbose("\tAdding g711 alaw capability to call(%s, %s)\n",
431                                             call->callType, call->callToken);
432          txframes = prefs->framing[x];
433          ret= ooCallAddG711Capability(call, OO_G711ALAW64K, txframes, 
434                                      txframes, OORXANDTX, 
435                                      &ooh323c_start_receive_channel,
436                                      &ooh323c_start_transmit_channel,
437                                      &ooh323c_stop_receive_channel, 
438                                      &ooh323c_stop_transmit_channel);
439       }
440
441       if(tmpfmt.id == AST_FORMAT_G726)
442       {
443          if(gH323Debug)
444             ast_verbose("\tAdding g726 capability to call (%s, %s)\n",
445                                            call->callType, call->callToken);
446          txframes = prefs->framing[x];
447          ret = ooCallAddG726Capability(call, OO_G726, txframes, grxframes, FALSE,
448                                      OORXANDTX, &ooh323c_start_receive_channel,
449                                      &ooh323c_start_transmit_channel,
450                                      &ooh323c_stop_receive_channel, 
451                                      &ooh323c_stop_transmit_channel);
452
453       }
454
455       if(tmpfmt.id == AST_FORMAT_G726_AAL2)
456       {
457          if(gH323Debug)
458             ast_verbose("\tAdding g726aal2 capability to call (%s, %s)\n",
459                                            call->callType, call->callToken);
460          txframes = prefs->framing[x];
461          ret = ooCallAddG726Capability(call, OO_G726AAL2, txframes, grxframes, FALSE,
462                                      OORXANDTX, &ooh323c_start_receive_channel,
463                                      &ooh323c_start_transmit_channel,
464                                      &ooh323c_stop_receive_channel, 
465                                      &ooh323c_stop_transmit_channel);
466
467       }
468
469       if(tmpfmt.id == AST_FORMAT_G729A)
470       {
471       
472          txframes = (prefs->framing[x])/10;
473          if(gH323Debug)
474             ast_verbose("\tAdding g729A capability to call(%s, %s)\n",
475                                             call->callType, call->callToken);
476          ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes, 
477                                      OORXANDTX, &ooh323c_start_receive_channel,
478                                      &ooh323c_start_transmit_channel,
479                                      &ooh323c_stop_receive_channel, 
480                                      &ooh323c_stop_transmit_channel);
481          if (g729onlyA)
482                 continue;
483          if(gH323Debug)
484             ast_verbose("\tAdding g729 capability to call(%s, %s)\n",
485                                             call->callType, call->callToken);
486          ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes, 
487                                      OORXANDTX, &ooh323c_start_receive_channel,
488                                      &ooh323c_start_transmit_channel,
489                                      &ooh323c_stop_receive_channel, 
490                                      &ooh323c_stop_transmit_channel);
491          if(gH323Debug)
492             ast_verbose("\tAdding g729B capability to call(%s, %s)\n",
493                                             call->callType, call->callToken);
494          ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes, 
495                                      OORXANDTX, &ooh323c_start_receive_channel,
496                                      &ooh323c_start_transmit_channel,
497                                      &ooh323c_stop_receive_channel, 
498                                      &ooh323c_stop_transmit_channel);
499
500       }
501
502       if(tmpfmt.id == AST_FORMAT_G723_1)
503       {
504          if(gH323Debug)
505             ast_verbose("\tAdding g7231 capability to call (%s, %s)\n",
506                                            call->callType, call->callToken);
507          ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE, 
508                                      OORXANDTX, &ooh323c_start_receive_channel,
509                                      &ooh323c_start_transmit_channel,
510                                      &ooh323c_stop_receive_channel, 
511                                      &ooh323c_stop_transmit_channel);
512
513       }
514
515       if(tmpfmt.id == AST_FORMAT_H263)
516       {
517          if(gH323Debug)
518             ast_verbose("\tAdding h263 capability to call (%s, %s)\n",
519                                            call->callType, call->callToken);
520          ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, 
521                                      OORXANDTX, &ooh323c_start_receive_channel,
522                                      &ooh323c_start_transmit_channel,
523                                      &ooh323c_stop_receive_channel, 
524                                      &ooh323c_stop_transmit_channel);
525
526       }
527
528       if(tmpfmt.id == AST_FORMAT_GSM)
529       {
530          if(gH323Debug)
531             ast_verbose("\tAdding gsm capability to call(%s, %s)\n", 
532                                              call->callType, call->callToken);
533          ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE, 
534                                      OORXANDTX, &ooh323c_start_receive_channel,
535                                      &ooh323c_start_transmit_channel,
536                                      &ooh323c_stop_receive_channel, 
537                                      &ooh323c_stop_transmit_channel);
538       }
539
540 #ifdef AST_FORMAT_AMRNB
541       if(tmpfmt.id == AST_FORMAT_AMRNB)
542       {
543          if(gH323Debug)
544             ast_verbose("\tAdding AMR capability to call(%s, %s)\n", 
545                                              call->callType, call->callToken);
546          ret = ooCallAddAMRNBCapability(call, OO_AMRNB, 4, 4, FALSE, 
547                                      OORXANDTX, &ooh323c_start_receive_channel,
548                                      &ooh323c_start_transmit_channel,
549                                      &ooh323c_stop_receive_channel, 
550                                      &ooh323c_stop_transmit_channel);
551       }
552 #endif
553 #ifdef AST_FORMAT_SPEEX
554       if(tmpfmt.id == AST_FORMAT_SPEEX)
555       {
556          if(gH323Debug)
557             ast_verbose("\tAdding Speex capability to call(%s, %s)\n", 
558                                              call->callType, call->callToken);
559          ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE, 
560                                      OORXANDTX, &ooh323c_start_receive_channel,
561                                      &ooh323c_start_transmit_channel,
562                                      &ooh323c_stop_receive_channel, 
563                                      &ooh323c_stop_transmit_channel);
564       }
565 #endif
566    }
567    return ret;
568 }
569
570 int ooh323c_set_aliases(ooAliases * aliases)
571 {
572    ooAliases *cur = aliases;
573    while(cur)
574    {
575       switch(cur->type)
576       { 
577       case T_H225AliasAddress_dialedDigits:
578          ooH323EpAddAliasDialedDigits(cur->value);
579          break;
580       case T_H225AliasAddress_h323_ID:
581          ooH323EpAddAliasH323ID(cur->value);
582          break;
583       case T_H225AliasAddress_url_ID:
584          ooH323EpAddAliasURLID(cur->value);
585          break;
586       case T_H225AliasAddress_email_ID:
587          ooH323EpAddAliasEmailID(cur->value);
588          break;
589       default:
590          ast_debug(1, "Ignoring unknown alias type\n");
591       }
592       cur = cur->next;
593    }
594    return 1;
595 }
596    
597 int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
598 {
599    struct ast_format tmpfmt;
600    convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
601    if(tmpfmt.id) {
602       /* ooh323_set_read_format(call, fmt); */
603    }else{
604      ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
605                                                           call->callToken);
606      return -1;
607    }
608    return 1;
609 }
610
611 int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
612 {
613    struct ast_format tmpfmt;
614    convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
615    if(tmpfmt.id) {
616       switch (tmpfmt.id) {
617       case AST_FORMAT_ALAW:
618       case AST_FORMAT_ULAW:
619         ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
620         break;
621       case AST_FORMAT_G729A:
622         ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
623         break;
624       default:
625         ooh323_set_write_format(call, &tmpfmt, 0);
626       }
627    }else{
628       ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
629                                                           call->callToken);
630       return -1;
631    }
632    setup_rtp_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
633     return 1;
634 }
635
636 int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
637 {
638    return 1;
639 }
640
641 int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
642 {
643    close_rtp_connection(call);
644    return 1;
645 }
646
647
648 int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
649 {
650    return 1;
651 }
652
653 int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
654 {
655    setup_udptl_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
656    return 1;
657 }
658
659 int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
660 {
661    return 1;
662 }
663
664 int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
665 {
666    close_udptl_connection(call);
667    return 1;
668 }
669
670 struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *result)
671 {
672    ast_format_clear(result);
673    switch(cap)
674    {
675       case OO_G711ULAW64K:
676          return ast_format_set(result, AST_FORMAT_ULAW, 0);
677       case OO_G711ALAW64K:
678          return ast_format_set(result, AST_FORMAT_ALAW, 0);
679       case OO_GSMFULLRATE:
680          return ast_format_set(result, AST_FORMAT_GSM, 0);
681
682 #ifdef AST_FORMAT_AMRNB
683       case OO_AMRNB:
684          return ast_format_set(result, AST_FORMAT_AMRNB, 0);
685 #endif
686 #ifdef AST_FORMAT_SPEEX
687       case OO_SPEEX:
688          return ast_format_set(result, AST_FORMAT_SPEEX, 0);
689 #endif
690
691       case OO_G729:
692          return ast_format_set(result, AST_FORMAT_G729A, 0);
693       case OO_G729A:
694          return ast_format_set(result, AST_FORMAT_G729A, 0);
695       case OO_G729B:
696          return ast_format_set(result, AST_FORMAT_G729A, 0);
697       case OO_G7231:
698          return ast_format_set(result, AST_FORMAT_G723_1, 0);
699       case OO_G726:
700          return ast_format_set(result, AST_FORMAT_G726, 0);
701       case OO_G726AAL2:
702          return ast_format_set(result, AST_FORMAT_G726_AAL2, 0);
703       case OO_H263VIDEO:
704          return ast_format_set(result, AST_FORMAT_H263, 0);
705       default:
706          ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
707          return NULL;
708    }
709
710    return NULL;
711 }
712
713