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