media formats: re-architect handling of media for performance improvements
[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 = 0;
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 && res >= 0);
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  struct callthread *cur = callThreads;
133
134  ast_mutex_lock(&callThreadsLock);
135  while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) {
136         cur = cur->next;
137  }
138  ast_mutex_unlock(&callThreadsLock);
139
140  if (cur != NULL) {
141    if (cur->inUse || write(cur->thePipe[1], &c, 1) < 0) {
142         ast_mutex_unlock(&cur->lock);
143         cur = NULL;
144    }
145  }
146
147 /* make new thread */
148  if (cur == NULL) {
149         if (!(cur = ast_calloc(1, sizeof(struct callthread)))) {
150                 ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n",
151                                                         call->callToken);
152                 return -1;
153         }
154
155         ast_module_ref(myself);
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         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_format_cap *cap, int dtmf, int dtmfcodec)
229 {
230    int ret = 0, x;
231    if (gH323Debug) {
232      ast_verb(0, "\tAdding capabilities to H323 endpoint\n");
233    }
234
235    for(x=0; x<ast_format_cap_count(cap); x++)
236    {
237     struct ast_format *format = ast_format_cap_get_format(cap, x);
238       if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL)
239       {
240          if (gH323Debug) {
241             ast_verb(0, "\tAdding g711 ulaw capability to H323 endpoint\n");
242          }
243          ret= ooH323EpAddG711Capability(OO_G711ULAW64K, gtxframes, grxframes, 
244                                      OORXANDTX, &ooh323c_start_receive_channel,
245                                      &ooh323c_start_transmit_channel,
246                                      &ooh323c_stop_receive_channel, 
247                                      &ooh323c_stop_transmit_channel);
248       }
249       if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL)
250       {
251          if (gH323Debug) {
252             ast_verb(0, "\tAdding g711 alaw capability to H323 endpoint\n");
253          }
254          ret= ooH323EpAddG711Capability(OO_G711ALAW64K, gtxframes, grxframes, 
255                                      OORXANDTX, &ooh323c_start_receive_channel,
256                                      &ooh323c_start_transmit_channel,
257                                      &ooh323c_stop_receive_channel, 
258                                      &ooh323c_stop_transmit_channel);
259       }
260
261       if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL)
262       {
263          if (gH323Debug) {
264             ast_verb(0, "\tAdding g729A capability to H323 endpoint\n");
265          }
266          ret = ooH323EpAddG729Capability(OO_G729A, 2, 24, 
267                                      OORXANDTX, &ooh323c_start_receive_channel,
268                                      &ooh323c_start_transmit_channel,
269                                      &ooh323c_stop_receive_channel, 
270                                      &ooh323c_stop_transmit_channel);
271
272          if (gH323Debug) {
273             ast_verb(0, "\tAdding g729 capability to H323 endpoint\n");
274          }
275          ret |= ooH323EpAddG729Capability(OO_G729, 2, 24, 
276                                      OORXANDTX, &ooh323c_start_receive_channel,
277                                      &ooh323c_start_transmit_channel,
278                                      &ooh323c_stop_receive_channel, 
279                                      &ooh323c_stop_transmit_channel);
280          if (gH323Debug) {
281             ast_verb(0, "\tAdding g729b capability to H323 endpoint\n");
282          }
283          ret |= ooH323EpAddG729Capability(OO_G729B, 2, 24, 
284                                      OORXANDTX, &ooh323c_start_receive_channel,
285                                      &ooh323c_start_transmit_channel,
286                                      &ooh323c_stop_receive_channel, 
287                                      &ooh323c_stop_transmit_channel);
288       }
289
290       if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL)
291       {
292          if (gH323Debug) {
293             ast_verb(0, "\tAdding g7231 capability to H323 endpoint\n");
294          }
295          ret = ooH323EpAddG7231Capability(OO_G7231, 1, 1, FALSE, 
296                                      OORXANDTX, &ooh323c_start_receive_channel,
297                                      &ooh323c_start_transmit_channel,
298                                      &ooh323c_stop_receive_channel, 
299                                      &ooh323c_stop_transmit_channel);
300
301       }
302
303       if(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL)
304       {
305          if (gH323Debug) {
306             ast_verb(0, "\tAdding g726 capability to H323 endpoint\n");
307          }
308          ret = ooH323EpAddG726Capability(OO_G726, gtxframes, grxframes, FALSE, 
309                                      OORXANDTX, &ooh323c_start_receive_channel,
310                                      &ooh323c_start_transmit_channel,
311                                      &ooh323c_stop_receive_channel, 
312                                      &ooh323c_stop_transmit_channel);
313
314       }
315
316       if(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL)
317       {
318          if (gH323Debug) {
319             ast_verb(0, "\tAdding g726aal2 capability to H323 endpoint\n");
320          }
321          ret = ooH323EpAddG726Capability(OO_G726AAL2, gtxframes, grxframes, FALSE, 
322                                      OORXANDTX, &ooh323c_start_receive_channel,
323                                      &ooh323c_start_transmit_channel,
324                                      &ooh323c_stop_receive_channel, 
325                                      &ooh323c_stop_transmit_channel);
326
327       }
328
329       if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL)
330       {
331          if (gH323Debug) {
332             ast_verb(0, "\tAdding h263 capability to H323 endpoint\n");
333          }
334          ret = ooH323EpAddH263VideoCapability(OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, 
335                                      OORXANDTX, &ooh323c_start_receive_channel,
336                                      &ooh323c_start_transmit_channel,
337                                      &ooh323c_stop_receive_channel, 
338                                      &ooh323c_stop_transmit_channel);
339
340       }
341
342       if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL)
343       {
344          if (gH323Debug) {
345             ast_verb(0, "\tAdding gsm capability to H323 endpoint\n");
346          }
347          ret = ooH323EpAddGSMCapability(OO_GSMFULLRATE, 4, FALSE, FALSE, 
348                                      OORXANDTX, &ooh323c_start_receive_channel,
349                                      &ooh323c_start_transmit_channel,
350                                      &ooh323c_stop_receive_channel, 
351                                      &ooh323c_stop_transmit_channel);
352
353       }
354
355       if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL)
356       {
357          if (gH323Debug) {
358             ast_verb(0, "\tAdding speex capability to H323 endpoint\n");
359          }
360          ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE, 
361                                      OORXANDTX, &ooh323c_start_receive_channel,
362                                      &ooh323c_start_transmit_channel,
363                                      &ooh323c_stop_receive_channel, 
364                                      &ooh323c_stop_transmit_channel);
365
366       }
367
368     ao2_ref(format, -1);      
369    }
370    
371    if(dtmf & H323_DTMF_CISCO)
372       ret |= ooH323EpEnableDTMFCISCO(0);
373    if(dtmf & H323_DTMF_RFC2833)
374       ret |= ooH323EpEnableDTMFRFC2833(0);
375    else if(dtmf & H323_DTMF_H245ALPHANUMERIC)
376       ret |= ooH323EpEnableDTMFH245Alphanumeric();
377    else if(dtmf & H323_DTMF_H245SIGNAL)
378       ret |= ooH323EpEnableDTMFH245Signal();
379
380    return ret;
381 }
382
383 int ooh323c_set_capability_for_call
384    (ooCallData *call, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
385                  int t38support, int g729onlyA)
386 {
387    int ret = 0, x, txframes;
388    if (gH323Debug) {
389      ast_verb(0, "\tAdding capabilities to call(%s, %s)\n", call->callType, 
390                                                             call->callToken);
391    }
392    if(dtmf & H323_DTMF_CISCO || 1)
393       ret |= ooCallEnableDTMFCISCO(call,dtmfcodec);
394    if(dtmf & H323_DTMF_RFC2833 || 1)
395       ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec);
396    if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1)
397       ret |= ooCallEnableDTMFH245Alphanumeric(call);
398    if(dtmf & H323_DTMF_H245SIGNAL || 1)
399       ret |= ooCallEnableDTMFH245Signal(call);
400
401    if (t38support)
402         ooCapabilityAddT38Capability(call, OO_T38, OORXANDTX, 
403                                         &ooh323c_start_receive_datachannel,
404                                         &ooh323c_start_transmit_datachannel,
405                                         &ooh323c_stop_receive_datachannel,
406                                         &ooh323c_stop_transmit_datachannel,
407                                         0);
408
409    for(x=0; x<ast_format_cap_count(cap); x++)
410    {
411     struct ast_format *format = ast_format_cap_get_format(cap, x);
412       if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL)
413       {
414          if (gH323Debug) {
415             ast_verb(0, "\tAdding g711 ulaw capability to call(%s, %s)\n", 
416                                               call->callType, call->callToken);
417          }
418          txframes = ast_format_cap_get_format_framing(cap, format);
419          ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes, 
420                                       txframes, OORXANDTX, 
421                                       &ooh323c_start_receive_channel,
422                                       &ooh323c_start_transmit_channel,
423                                       &ooh323c_stop_receive_channel, 
424                                       &ooh323c_stop_transmit_channel);
425       }
426       if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL)
427       {
428          if (gH323Debug) {
429             ast_verb(0, "\tAdding g711 alaw capability to call(%s, %s)\n",
430                                             call->callType, call->callToken);
431          }
432          txframes = ast_format_cap_get_format_framing(cap, format);
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(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL)
442       {
443          if (gH323Debug) {
444             ast_verb(0, "\tAdding g726 capability to call (%s, %s)\n",
445                                            call->callType, call->callToken);
446          }
447          txframes = ast_format_cap_get_format_framing(cap, format);
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(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL)
457       {
458          if (gH323Debug) {
459             ast_verb(0, "\tAdding g726aal2 capability to call (%s, %s)\n",
460                                            call->callType, call->callToken);
461          }
462          txframes = ast_format_cap_get_format_framing(cap, format);
463          ret = ooCallAddG726Capability(call, OO_G726AAL2, txframes, grxframes, FALSE,
464                                      OORXANDTX, &ooh323c_start_receive_channel,
465                                      &ooh323c_start_transmit_channel,
466                                      &ooh323c_stop_receive_channel, 
467                                      &ooh323c_stop_transmit_channel);
468
469       }
470
471       if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL)
472       {
473       
474          txframes = (ast_format_cap_get_format_framing(cap, format))/10;
475          if (gH323Debug) {
476             ast_verb(0, "\tAdding g729A capability to call(%s, %s)\n",
477                                             call->callType, call->callToken);
478          }
479          ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes, 
480                                      OORXANDTX, &ooh323c_start_receive_channel,
481                                      &ooh323c_start_transmit_channel,
482                                      &ooh323c_stop_receive_channel, 
483                                      &ooh323c_stop_transmit_channel);
484          if (g729onlyA)
485                 continue;
486          if (gH323Debug) {
487             ast_verb(0, "\tAdding g729 capability to call(%s, %s)\n",
488                                             call->callType, call->callToken);
489          }
490          ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes, 
491                                      OORXANDTX, &ooh323c_start_receive_channel,
492                                      &ooh323c_start_transmit_channel,
493                                      &ooh323c_stop_receive_channel, 
494                                      &ooh323c_stop_transmit_channel);
495          if (gH323Debug) {
496             ast_verb(0, "\tAdding g729B capability to call(%s, %s)\n",
497                                             call->callType, call->callToken);
498          }
499          ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes, 
500                                      OORXANDTX, &ooh323c_start_receive_channel,
501                                      &ooh323c_start_transmit_channel,
502                                      &ooh323c_stop_receive_channel, 
503                                      &ooh323c_stop_transmit_channel);
504
505       }
506
507       if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL)
508       {
509          if (gH323Debug) {
510             ast_verb(0, "\tAdding g7231 capability to call (%s, %s)\n",
511                                            call->callType, call->callToken);
512          }
513          ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE, 
514                                      OORXANDTX, &ooh323c_start_receive_channel,
515                                      &ooh323c_start_transmit_channel,
516                                      &ooh323c_stop_receive_channel, 
517                                      &ooh323c_stop_transmit_channel);
518
519       }
520
521       if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL)
522       {
523          if (gH323Debug) {
524             ast_verb(0, "\tAdding h263 capability to call (%s, %s)\n",
525                                            call->callType, call->callToken);
526          }
527          ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, 
528                                      OORXANDTX, &ooh323c_start_receive_channel,
529                                      &ooh323c_start_transmit_channel,
530                                      &ooh323c_stop_receive_channel, 
531                                      &ooh323c_stop_transmit_channel);
532
533       }
534
535       if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL)
536       {
537          if (gH323Debug) {
538             ast_verb(0, "\tAdding gsm capability to call(%s, %s)\n", 
539                                              call->callType, call->callToken);
540          }
541          ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE, 
542                                      OORXANDTX, &ooh323c_start_receive_channel,
543                                      &ooh323c_start_transmit_channel,
544                                      &ooh323c_stop_receive_channel, 
545                                      &ooh323c_stop_transmit_channel);
546       }
547
548       if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL)
549       {
550          if (gH323Debug) {
551             ast_verb(0, "\tAdding Speex capability to call(%s, %s)\n", 
552                                              call->callType, call->callToken);
553          }
554          ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE, 
555                                      OORXANDTX, &ooh323c_start_receive_channel,
556                                      &ooh323c_start_transmit_channel,
557                                      &ooh323c_stop_receive_channel, 
558                                      &ooh323c_stop_transmit_channel);
559       }
560
561       ao2_ref(format, -1);
562    }
563    return ret;
564 }
565
566 int ooh323c_set_aliases(ooAliases * aliases)
567 {
568    ooAliases *cur = aliases;
569    while(cur)
570    {
571       switch(cur->type)
572       { 
573       case T_H225AliasAddress_dialedDigits:
574          ooH323EpAddAliasDialedDigits(cur->value);
575          break;
576       case T_H225AliasAddress_h323_ID:
577          ooH323EpAddAliasH323ID(cur->value);
578          break;
579       case T_H225AliasAddress_url_ID:
580          ooH323EpAddAliasURLID(cur->value);
581          break;
582       case T_H225AliasAddress_email_ID:
583          ooH323EpAddAliasEmailID(cur->value);
584          break;
585       default:
586          ast_debug(1, "Ignoring unknown alias type\n");
587       }
588       cur = cur->next;
589    }
590    return 1;
591 }
592    
593 int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
594 {
595    struct ast_format *tmpfmt = NULL;
596    tmpfmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
597    if(tmpfmt) {
598       /* ooh323_set_read_format(call, fmt); */
599    }else{
600      ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
601                                                           call->callToken);
602      return -1;
603    }
604    return 1;
605 }
606
607 int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
608 {
609    struct ast_format *tmpfmt = NULL;
610    tmpfmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
611
612    if (tmpfmt) {
613     if ((ast_format_cmp(tmpfmt, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) ||
614       (ast_format_cmp(tmpfmt, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL)) {
615         ooh323_set_write_format(call, tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
616     } else if (ast_format_cmp(tmpfmt, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
617          ooh323_set_write_format(call, tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
618   } else {
619         ooh323_set_write_format(call, tmpfmt, 0);
620       }
621    }else{
622       ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
623                                                           call->callToken);
624       return -1;
625    }
626    setup_rtp_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
627     return 1;
628 }
629
630 int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
631 {
632    return 1;
633 }
634
635 int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
636 {
637    close_rtp_connection(call);
638    return 1;
639 }
640
641
642 int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
643 {
644    return 1;
645 }
646
647 int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
648 {
649    setup_udptl_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
650    return 1;
651 }
652
653 int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
654 {
655    return 1;
656 }
657
658 int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
659 {
660    close_udptl_connection(call);
661    return 1;
662 }
663
664 struct ast_format *convertH323CapToAsteriskCap(int cap)
665 {
666    switch(cap)
667    {
668       case OO_G711ULAW64K:
669          return ast_format_ulaw;
670       case OO_G711ALAW64K:
671          return ast_format_alaw;
672       case OO_GSMFULLRATE:
673          return ast_format_gsm;
674       case OO_SPEEX:
675          return ast_format_speex;
676       case OO_G729:
677          return ast_format_g729;
678       case OO_G729A:
679          return ast_format_g729;
680       case OO_G729B:
681          return ast_format_g729;
682       case OO_G7231:
683          return ast_format_g723;
684       case OO_G726:
685          return ast_format_g726;
686       case OO_G726AAL2:
687          return ast_format_g726_aal2;
688       case OO_H263VIDEO:
689          return ast_format_h263;
690       default:
691          ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
692          return NULL;
693    }
694
695    return NULL;
696 }
697
698