dd127a49993abd5d2fef2cfc7918f787fbf54cb3
[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_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_verb(0, "\tAdding capabilities to H323 endpoint\n");
234    }
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_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(tmpfmt.id == AST_FORMAT_ALAW)
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(tmpfmt.id == AST_FORMAT_G729A)
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(tmpfmt.id == AST_FORMAT_G723_1)
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(tmpfmt.id == AST_FORMAT_G726)
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(tmpfmt.id == AST_FORMAT_G726_AAL2)
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(tmpfmt.id == AST_FORMAT_H263)
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(tmpfmt.id == AST_FORMAT_GSM)
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 #ifdef AST_FORMAT_AMRNB
356       if(tmpfmt.id == AST_FORMAT_AMRNB)
357       {
358          if (gH323Debug) {
359             ast_verb(0, "\tAdding amr nb capability to H323 endpoint\n");
360          }
361          ret = ooH323EpAddAMRNBCapability(OO_AMRNB, 4, 4, FALSE, 
362                                      OORXANDTX, &ooh323c_start_receive_channel,
363                                      &ooh323c_start_transmit_channel,
364                                      &ooh323c_stop_receive_channel, 
365                                      &ooh323c_stop_transmit_channel);
366
367       }
368 #endif
369
370 #ifdef AST_FORMAT_SPEEX
371       if(tmpfmt.id == AST_FORMAT_SPEEX)
372       {
373          if (gH323Debug) {
374             ast_verb(0, "\tAdding speex capability to H323 endpoint\n");
375          }
376          ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE, 
377                                      OORXANDTX, &ooh323c_start_receive_channel,
378                                      &ooh323c_start_transmit_channel,
379                                      &ooh323c_stop_receive_channel, 
380                                      &ooh323c_stop_transmit_channel);
381
382       }
383 #endif
384       
385    }
386    
387    if(dtmf & H323_DTMF_CISCO)
388       ret |= ooH323EpEnableDTMFCISCO(0);
389    if(dtmf & H323_DTMF_RFC2833)
390       ret |= ooH323EpEnableDTMFRFC2833(0);
391    else if(dtmf & H323_DTMF_H245ALPHANUMERIC)
392       ret |= ooH323EpEnableDTMFH245Alphanumeric();
393    else if(dtmf & H323_DTMF_H245SIGNAL)
394       ret |= ooH323EpEnableDTMFH245Signal();
395
396    return ret;
397 }
398
399 int ooh323c_set_capability_for_call
400    (ooCallData *call, struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
401                  int t38support, int g729onlyA)
402 {
403    int ret = 0, x, txframes;
404    struct ast_format tmpfmt;
405    if (gH323Debug) {
406      ast_verb(0, "\tAdding capabilities to call(%s, %s)\n", call->callType, 
407                                                             call->callToken);
408    }
409    if(dtmf & H323_DTMF_CISCO || 1)
410       ret |= ooCallEnableDTMFCISCO(call,dtmfcodec);
411    if(dtmf & H323_DTMF_RFC2833 || 1)
412       ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec);
413    if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1)
414       ret |= ooCallEnableDTMFH245Alphanumeric(call);
415    if(dtmf & H323_DTMF_H245SIGNAL || 1)
416       ret |= ooCallEnableDTMFH245Signal(call);
417
418    if (t38support)
419         ooCapabilityAddT38Capability(call, OO_T38, OORXANDTX, 
420                                         &ooh323c_start_receive_datachannel,
421                                         &ooh323c_start_transmit_datachannel,
422                                         &ooh323c_stop_receive_datachannel,
423                                         &ooh323c_stop_transmit_datachannel,
424                                         0);
425
426    for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
427    {
428       if(tmpfmt.id == AST_FORMAT_ULAW)
429       {
430          if (gH323Debug) {
431             ast_verb(0, "\tAdding g711 ulaw capability to call(%s, %s)\n", 
432                                               call->callType, call->callToken);
433          }
434          txframes = prefs->framing[x];
435          ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes, 
436                                       txframes, OORXANDTX, 
437                                       &ooh323c_start_receive_channel,
438                                       &ooh323c_start_transmit_channel,
439                                       &ooh323c_stop_receive_channel, 
440                                       &ooh323c_stop_transmit_channel);
441       }
442       if(tmpfmt.id == AST_FORMAT_ALAW)
443       {
444          if (gH323Debug) {
445             ast_verb(0, "\tAdding g711 alaw capability to call(%s, %s)\n",
446                                             call->callType, call->callToken);
447          }
448          txframes = prefs->framing[x];
449          ret= ooCallAddG711Capability(call, OO_G711ALAW64K, txframes, 
450                                      txframes, OORXANDTX, 
451                                      &ooh323c_start_receive_channel,
452                                      &ooh323c_start_transmit_channel,
453                                      &ooh323c_stop_receive_channel, 
454                                      &ooh323c_stop_transmit_channel);
455       }
456
457       if(tmpfmt.id == AST_FORMAT_G726)
458       {
459          if (gH323Debug) {
460             ast_verb(0, "\tAdding g726 capability to call (%s, %s)\n",
461                                            call->callType, call->callToken);
462          }
463          txframes = prefs->framing[x];
464          ret = ooCallAddG726Capability(call, OO_G726, txframes, grxframes, FALSE,
465                                      OORXANDTX, &ooh323c_start_receive_channel,
466                                      &ooh323c_start_transmit_channel,
467                                      &ooh323c_stop_receive_channel, 
468                                      &ooh323c_stop_transmit_channel);
469
470       }
471
472       if(tmpfmt.id == AST_FORMAT_G726_AAL2)
473       {
474          if (gH323Debug) {
475             ast_verb(0, "\tAdding g726aal2 capability to call (%s, %s)\n",
476                                            call->callType, call->callToken);
477          }
478          txframes = prefs->framing[x];
479          ret = ooCallAddG726Capability(call, OO_G726AAL2, txframes, grxframes, FALSE,
480                                      OORXANDTX, &ooh323c_start_receive_channel,
481                                      &ooh323c_start_transmit_channel,
482                                      &ooh323c_stop_receive_channel, 
483                                      &ooh323c_stop_transmit_channel);
484
485       }
486
487       if(tmpfmt.id == AST_FORMAT_G729A)
488       {
489       
490          txframes = (prefs->framing[x])/10;
491          if (gH323Debug) {
492             ast_verb(0, "\tAdding g729A capability to call(%s, %s)\n",
493                                             call->callType, call->callToken);
494          }
495          ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes, 
496                                      OORXANDTX, &ooh323c_start_receive_channel,
497                                      &ooh323c_start_transmit_channel,
498                                      &ooh323c_stop_receive_channel, 
499                                      &ooh323c_stop_transmit_channel);
500          if (g729onlyA)
501                 continue;
502          if (gH323Debug) {
503             ast_verb(0, "\tAdding g729 capability to call(%s, %s)\n",
504                                             call->callType, call->callToken);
505          }
506          ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes, 
507                                      OORXANDTX, &ooh323c_start_receive_channel,
508                                      &ooh323c_start_transmit_channel,
509                                      &ooh323c_stop_receive_channel, 
510                                      &ooh323c_stop_transmit_channel);
511          if (gH323Debug) {
512             ast_verb(0, "\tAdding g729B capability to call(%s, %s)\n",
513                                             call->callType, call->callToken);
514          }
515          ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes, 
516                                      OORXANDTX, &ooh323c_start_receive_channel,
517                                      &ooh323c_start_transmit_channel,
518                                      &ooh323c_stop_receive_channel, 
519                                      &ooh323c_stop_transmit_channel);
520
521       }
522
523       if(tmpfmt.id == AST_FORMAT_G723_1)
524       {
525          if (gH323Debug) {
526             ast_verb(0, "\tAdding g7231 capability to call (%s, %s)\n",
527                                            call->callType, call->callToken);
528          }
529          ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE, 
530                                      OORXANDTX, &ooh323c_start_receive_channel,
531                                      &ooh323c_start_transmit_channel,
532                                      &ooh323c_stop_receive_channel, 
533                                      &ooh323c_stop_transmit_channel);
534
535       }
536
537       if(tmpfmt.id == AST_FORMAT_H263)
538       {
539          if (gH323Debug) {
540             ast_verb(0, "\tAdding h263 capability to call (%s, %s)\n",
541                                            call->callType, call->callToken);
542          }
543          ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, 
544                                      OORXANDTX, &ooh323c_start_receive_channel,
545                                      &ooh323c_start_transmit_channel,
546                                      &ooh323c_stop_receive_channel, 
547                                      &ooh323c_stop_transmit_channel);
548
549       }
550
551       if(tmpfmt.id == AST_FORMAT_GSM)
552       {
553          if (gH323Debug) {
554             ast_verb(0, "\tAdding gsm capability to call(%s, %s)\n", 
555                                              call->callType, call->callToken);
556          }
557          ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE, 
558                                      OORXANDTX, &ooh323c_start_receive_channel,
559                                      &ooh323c_start_transmit_channel,
560                                      &ooh323c_stop_receive_channel, 
561                                      &ooh323c_stop_transmit_channel);
562       }
563
564 #ifdef AST_FORMAT_AMRNB
565       if(tmpfmt.id == AST_FORMAT_AMRNB)
566       {
567          if (gH323Debug) {
568             ast_verb(0, "\tAdding AMR capability to call(%s, %s)\n", 
569                                              call->callType, call->callToken);
570          }
571          ret = ooCallAddAMRNBCapability(call, OO_AMRNB, 4, 4, FALSE, 
572                                      OORXANDTX, &ooh323c_start_receive_channel,
573                                      &ooh323c_start_transmit_channel,
574                                      &ooh323c_stop_receive_channel, 
575                                      &ooh323c_stop_transmit_channel);
576       }
577 #endif
578 #ifdef AST_FORMAT_SPEEX
579       if(tmpfmt.id == AST_FORMAT_SPEEX)
580       {
581          if (gH323Debug) {
582             ast_verb(0, "\tAdding Speex capability to call(%s, %s)\n", 
583                                              call->callType, call->callToken);
584          }
585          ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE, 
586                                      OORXANDTX, &ooh323c_start_receive_channel,
587                                      &ooh323c_start_transmit_channel,
588                                      &ooh323c_stop_receive_channel, 
589                                      &ooh323c_stop_transmit_channel);
590       }
591 #endif
592    }
593    return ret;
594 }
595
596 int ooh323c_set_aliases(ooAliases * aliases)
597 {
598    ooAliases *cur = aliases;
599    while(cur)
600    {
601       switch(cur->type)
602       { 
603       case T_H225AliasAddress_dialedDigits:
604          ooH323EpAddAliasDialedDigits(cur->value);
605          break;
606       case T_H225AliasAddress_h323_ID:
607          ooH323EpAddAliasH323ID(cur->value);
608          break;
609       case T_H225AliasAddress_url_ID:
610          ooH323EpAddAliasURLID(cur->value);
611          break;
612       case T_H225AliasAddress_email_ID:
613          ooH323EpAddAliasEmailID(cur->value);
614          break;
615       default:
616          ast_debug(1, "Ignoring unknown alias type\n");
617       }
618       cur = cur->next;
619    }
620    return 1;
621 }
622    
623 int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
624 {
625    struct ast_format tmpfmt;
626    convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
627    if(tmpfmt.id) {
628       /* ooh323_set_read_format(call, fmt); */
629    }else{
630      ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
631                                                           call->callToken);
632      return -1;
633    }
634    return 1;
635 }
636
637 int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
638 {
639    struct ast_format tmpfmt;
640    convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
641    if(tmpfmt.id) {
642       switch (tmpfmt.id) {
643       case AST_FORMAT_ALAW:
644       case AST_FORMAT_ULAW:
645         ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
646         break;
647       case AST_FORMAT_G729A:
648         ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
649         break;
650       default:
651         ooh323_set_write_format(call, &tmpfmt, 0);
652       }
653    }else{
654       ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
655                                                           call->callToken);
656       return -1;
657    }
658    setup_rtp_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
659     return 1;
660 }
661
662 int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
663 {
664    return 1;
665 }
666
667 int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
668 {
669    close_rtp_connection(call);
670    return 1;
671 }
672
673
674 int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
675 {
676    return 1;
677 }
678
679 int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
680 {
681    setup_udptl_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
682    return 1;
683 }
684
685 int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
686 {
687    return 1;
688 }
689
690 int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
691 {
692    close_udptl_connection(call);
693    return 1;
694 }
695
696 struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *result)
697 {
698    ast_format_clear(result);
699    switch(cap)
700    {
701       case OO_G711ULAW64K:
702          return ast_format_set(result, AST_FORMAT_ULAW, 0);
703       case OO_G711ALAW64K:
704          return ast_format_set(result, AST_FORMAT_ALAW, 0);
705       case OO_GSMFULLRATE:
706          return ast_format_set(result, AST_FORMAT_GSM, 0);
707
708 #ifdef AST_FORMAT_AMRNB
709       case OO_AMRNB:
710          return ast_format_set(result, AST_FORMAT_AMRNB, 0);
711 #endif
712 #ifdef AST_FORMAT_SPEEX
713       case OO_SPEEX:
714          return ast_format_set(result, AST_FORMAT_SPEEX, 0);
715 #endif
716
717       case OO_G729:
718          return ast_format_set(result, AST_FORMAT_G729A, 0);
719       case OO_G729A:
720          return ast_format_set(result, AST_FORMAT_G729A, 0);
721       case OO_G729B:
722          return ast_format_set(result, AST_FORMAT_G729A, 0);
723       case OO_G7231:
724          return ast_format_set(result, AST_FORMAT_G723_1, 0);
725       case OO_G726:
726          return ast_format_set(result, AST_FORMAT_G726, 0);
727       case OO_G726AAL2:
728          return ast_format_set(result, AST_FORMAT_G726_AAL2, 0);
729       case OO_H263VIDEO:
730          return ast_format_set(result, AST_FORMAT_H263, 0);
731       default:
732          ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
733          return NULL;
734    }
735
736    return NULL;
737 }
738
739