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