Merged revisions 338995 via svnmerge from
[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, int g729onlyA)
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 g729A capability to call(%s, %s)\n",
476                                             call->callType, call->callToken);
477          ret= ooCallAddG729Capability(call, OO_G729A, 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 (g729onlyA)
483                 continue;
484          if(gH323Debug)
485             ast_verbose("\tAdding g729 capability to call(%s, %s)\n",
486                                             call->callType, call->callToken);
487          ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes, 
488                                      OORXANDTX, &ooh323c_start_receive_channel,
489                                      &ooh323c_start_transmit_channel,
490                                      &ooh323c_stop_receive_channel, 
491                                      &ooh323c_stop_transmit_channel);
492          if(gH323Debug)
493             ast_verbose("\tAdding g729B capability to call(%s, %s)\n",
494                                             call->callType, call->callToken);
495          ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes, 
496                                      OORXANDTX, &ooh323c_start_receive_channel,
497                                      &ooh323c_start_transmit_channel,
498                                      &ooh323c_stop_receive_channel, 
499                                      &ooh323c_stop_transmit_channel);
500
501       }
502
503       if(tmpfmt.id == AST_FORMAT_G723_1)
504       {
505          if(gH323Debug)
506             ast_verbose("\tAdding g7231 capability to call (%s, %s)\n",
507                                            call->callType, call->callToken);
508          ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE, 
509                                      OORXANDTX, &ooh323c_start_receive_channel,
510                                      &ooh323c_start_transmit_channel,
511                                      &ooh323c_stop_receive_channel, 
512                                      &ooh323c_stop_transmit_channel);
513
514       }
515
516       if(tmpfmt.id == AST_FORMAT_H263)
517       {
518          if(gH323Debug)
519             ast_verbose("\tAdding h263 capability to call (%s, %s)\n",
520                                            call->callType, call->callToken);
521          ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, 
522                                      OORXANDTX, &ooh323c_start_receive_channel,
523                                      &ooh323c_start_transmit_channel,
524                                      &ooh323c_stop_receive_channel, 
525                                      &ooh323c_stop_transmit_channel);
526
527       }
528
529       if(tmpfmt.id == AST_FORMAT_GSM)
530       {
531          if(gH323Debug)
532             ast_verbose("\tAdding gsm capability to call(%s, %s)\n", 
533                                              call->callType, call->callToken);
534          ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE, 
535                                      OORXANDTX, &ooh323c_start_receive_channel,
536                                      &ooh323c_start_transmit_channel,
537                                      &ooh323c_stop_receive_channel, 
538                                      &ooh323c_stop_transmit_channel);
539       }
540
541 #ifdef AST_FORMAT_AMRNB
542       if(tmpfmt.id == AST_FORMAT_AMRNB)
543       {
544          if(gH323Debug)
545             ast_verbose("\tAdding AMR capability to call(%s, %s)\n", 
546                                              call->callType, call->callToken);
547          ret = ooCallAddAMRNBCapability(call, OO_AMRNB, 4, 4, FALSE, 
548                                      OORXANDTX, &ooh323c_start_receive_channel,
549                                      &ooh323c_start_transmit_channel,
550                                      &ooh323c_stop_receive_channel, 
551                                      &ooh323c_stop_transmit_channel);
552       }
553 #endif
554 #ifdef AST_FORMAT_SPEEX
555       if(tmpfmt.id == AST_FORMAT_SPEEX)
556       {
557          if(gH323Debug)
558             ast_verbose("\tAdding Speex capability to call(%s, %s)\n", 
559                                              call->callType, call->callToken);
560          ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE, 
561                                      OORXANDTX, &ooh323c_start_receive_channel,
562                                      &ooh323c_start_transmit_channel,
563                                      &ooh323c_stop_receive_channel, 
564                                      &ooh323c_stop_transmit_channel);
565       }
566 #endif
567    }
568    return ret;
569 }
570
571 int ooh323c_set_aliases(ooAliases * aliases)
572 {
573    ooAliases *cur = aliases;
574    while(cur)
575    {
576       switch(cur->type)
577       { 
578       case T_H225AliasAddress_dialedDigits:
579          ooH323EpAddAliasDialedDigits(cur->value);
580          break;
581       case T_H225AliasAddress_h323_ID:
582          ooH323EpAddAliasH323ID(cur->value);
583          break;
584       case T_H225AliasAddress_url_ID:
585          ooH323EpAddAliasURLID(cur->value);
586          break;
587       case T_H225AliasAddress_email_ID:
588          ooH323EpAddAliasEmailID(cur->value);
589          break;
590       default:
591          ast_debug(1, "Ignoring unknown alias type\n");
592       }
593       cur = cur->next;
594    }
595    return 1;
596 }
597    
598 int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
599 {
600    struct ast_format tmpfmt;
601    convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
602    if(tmpfmt.id) {
603       /* ooh323_set_read_format(call, fmt); */
604    }else{
605      ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
606                                                           call->callToken);
607      return -1;
608    }
609    return 1;
610 }
611
612 int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
613 {
614    struct ast_format tmpfmt;
615    convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
616    if(tmpfmt.id) {
617       switch (tmpfmt.id) {
618       case AST_FORMAT_ALAW:
619       case AST_FORMAT_ULAW:
620         ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
621         break;
622       case AST_FORMAT_G729A:
623         ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
624         break;
625       default:
626         ooh323_set_write_format(call, &tmpfmt, 0);
627       }
628    }else{
629       ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
630                                                           call->callToken);
631       return -1;
632    }
633    setup_rtp_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
634     return 1;
635 }
636
637 int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
638 {
639    return 1;
640 }
641
642 int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
643 {
644    close_rtp_connection(call);
645    return 1;
646 }
647
648
649 int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
650 {
651    return 1;
652 }
653
654 int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
655 {
656    setup_udptl_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
657    return 1;
658 }
659
660 int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
661 {
662    return 1;
663 }
664
665 int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
666 {
667    close_udptl_connection(call);
668    return 1;
669 }
670
671 struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *result)
672 {
673    ast_format_clear(result);
674    switch(cap)
675    {
676       case OO_G711ULAW64K:
677          return ast_format_set(result, AST_FORMAT_ULAW, 0);
678       case OO_G711ALAW64K:
679          return ast_format_set(result, AST_FORMAT_ALAW, 0);
680       case OO_GSMFULLRATE:
681          return ast_format_set(result, AST_FORMAT_GSM, 0);
682
683 #ifdef AST_FORMAT_AMRNB
684       case OO_AMRNB:
685          return ast_format_set(result, AST_FORMAT_AMRNB, 0);
686 #endif
687 #ifdef AST_FORMAT_SPEEX
688       case OO_SPEEX:
689          return ast_format_set(result, AST_FORMAT_SPEEX, 0);
690 #endif
691
692       case OO_G729:
693          return ast_format_set(result, AST_FORMAT_G729A, 0);
694       case OO_G729A:
695          return ast_format_set(result, AST_FORMAT_G729A, 0);
696       case OO_G729B:
697          return ast_format_set(result, AST_FORMAT_G729A, 0);
698       case OO_G7231:
699          return ast_format_set(result, AST_FORMAT_G723_1, 0);
700       case OO_G726:
701          return ast_format_set(result, AST_FORMAT_G726, 0);
702       case OO_G726AAL2:
703          return ast_format_set(result, AST_FORMAT_G726_AAL2, 0);
704       case OO_H263VIDEO:
705          return ast_format_set(result, AST_FORMAT_H263, 0);
706       default:
707          ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
708          return NULL;
709    }
710
711    return NULL;
712 }
713
714