ooh323cDriver.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  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. #include "ooh323cDriver.h"
  17. #include "asterisk.h"
  18. #include "asterisk/lock.h"
  19. #include "asterisk/pbx.h"
  20. #include "asterisk/logger.h"
  21. #undef AST_BACKGROUND_STACKSIZE
  22. #define AST_BACKGROUND_STACKSIZE 768 * 1024
  23. #define SEC_TO_HOLD_THREAD 24
  24. extern struct ast_module *myself;
  25. extern OOBOOL gH323Debug;
  26. extern OOH323EndPoint gH323ep;
  27. /* ooh323c stack thread. */
  28. static pthread_t ooh323c_thread = AST_PTHREADT_NULL;
  29. static pthread_t ooh323cmd_thread = AST_PTHREADT_NULL;
  30. static int grxframes = 240;
  31. static int gtxframes = 20;
  32. static struct callthread {
  33. ast_mutex_t lock;
  34. int thePipe[2];
  35. OOBOOL inUse;
  36. ooCallData* call;
  37. struct callthread *next, *prev;
  38. } *callThreads = NULL;
  39. AST_MUTEX_DEFINE_STATIC(callThreadsLock);
  40. int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel);
  41. int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel);
  42. int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel);
  43. int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel);
  44. int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
  45. int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
  46. int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
  47. int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
  48. void* ooh323c_stack_thread(void* dummy);
  49. void* ooh323c_cmd_thread(void* dummy);
  50. void* ooh323c_call_thread(void* dummy);
  51. int ooh323c_set_aliases(ooAliases * aliases);
  52. void* ooh323c_stack_thread(void* dummy)
  53. {
  54. ooMonitorChannels();
  55. return dummy;
  56. }
  57. void* ooh323c_cmd_thread(void* dummy)
  58. {
  59. ooMonitorCmdChannels();
  60. return dummy;
  61. }
  62. void* ooh323c_call_thread(void* dummy)
  63. {
  64. struct callthread* mycthread = (struct callthread *)dummy;
  65. struct pollfd pfds[1];
  66. char c;
  67. int res = 0;
  68. do {
  69. ooMonitorCallChannels((ooCallData*)mycthread->call);
  70. mycthread->call = NULL;
  71. mycthread->prev = NULL;
  72. mycthread->inUse = FALSE;
  73. ast_mutex_lock(&callThreadsLock);
  74. mycthread->next = callThreads;
  75. callThreads = mycthread;
  76. if (mycthread->next) mycthread->next->prev = mycthread;
  77. ast_mutex_unlock(&callThreadsLock);
  78. pfds[0].fd = mycthread->thePipe[0];
  79. pfds[0].events = POLLIN;
  80. ooSocketPoll(pfds, 1, SEC_TO_HOLD_THREAD * 1000);
  81. if (ooPDRead(pfds, 1, mycthread->thePipe[0]))
  82. res = read(mycthread->thePipe[0], &c, 1);
  83. ast_mutex_lock(&callThreadsLock);
  84. ast_mutex_lock(&mycthread->lock);
  85. if (mycthread->prev)
  86. mycthread->prev->next = mycthread->next;
  87. else
  88. callThreads = mycthread->next;
  89. if (mycthread->next)
  90. mycthread->next->prev = mycthread->prev;
  91. ast_mutex_unlock(&mycthread->lock);
  92. ast_mutex_unlock(&callThreadsLock);
  93. } while (mycthread->call != NULL && res >= 0);
  94. ast_mutex_destroy(&mycthread->lock);
  95. close(mycthread->thePipe[0]);
  96. close(mycthread->thePipe[1]);
  97. ast_free(mycthread);
  98. ast_module_unref(myself);
  99. ast_update_use_count();
  100. return NULL;
  101. }
  102. int ooh323c_start_call_thread(ooCallData *call) {
  103. char c = 'c';
  104. struct callthread *cur = callThreads;
  105. ast_mutex_lock(&callThreadsLock);
  106. while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) {
  107. cur = cur->next;
  108. }
  109. ast_mutex_unlock(&callThreadsLock);
  110. if (cur != NULL) {
  111. if (cur->inUse || write(cur->thePipe[1], &c, 1) < 0) {
  112. ast_mutex_unlock(&cur->lock);
  113. cur = NULL;
  114. }
  115. }
  116. /* make new thread */
  117. if (cur == NULL) {
  118. if (!(cur = ast_calloc(1, sizeof(struct callthread)))) {
  119. ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n",
  120. call->callToken);
  121. return -1;
  122. }
  123. ast_module_ref(myself);
  124. if ((socketpair(PF_LOCAL, SOCK_STREAM, 0, cur->thePipe)) == -1) {
  125. ast_log(LOG_ERROR, "Can't create thread pipe for call %s\n", call->callToken);
  126. ast_free(cur);
  127. return -1;
  128. }
  129. cur->inUse = TRUE;
  130. cur->call = call;
  131. ast_mutex_init(&cur->lock);
  132. if (gH323Debug)
  133. ast_debug(1,"new call thread created for call %s\n", call->callToken);
  134. if(ast_pthread_create_detached_background(&call->callThread, NULL, ooh323c_call_thread, cur) < 0)
  135. {
  136. ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n",
  137. call->callToken);
  138. ast_mutex_destroy(&cur->lock);
  139. close(cur->thePipe[0]);
  140. close(cur->thePipe[1]);
  141. ast_free(cur);
  142. return -1;
  143. }
  144. } else {
  145. if (gH323Debug)
  146. ast_debug(1,"using existing call thread for call %s\n", call->callToken);
  147. cur->inUse = TRUE;
  148. cur->call = call;
  149. ast_mutex_unlock(&cur->lock);
  150. }
  151. return 0;
  152. }
  153. int ooh323c_stop_call_thread(ooCallData *call) {
  154. if (call->callThread != AST_PTHREADT_NULL) {
  155. ooStopMonitorCallChannels(call);
  156. }
  157. return 0;
  158. }
  159. int ooh323c_start_stack_thread()
  160. {
  161. if(ast_pthread_create_background(&ooh323c_thread, NULL, ooh323c_stack_thread, NULL) < 0)
  162. {
  163. ast_log(LOG_ERROR, "Unable to start ooh323c thread.\n");
  164. return -1;
  165. }
  166. if(ast_pthread_create_background(&ooh323cmd_thread, NULL, ooh323c_cmd_thread, NULL) < 0)
  167. {
  168. ast_log(LOG_ERROR, "Unable to start ooh323cmd thread.\n");
  169. return -1;
  170. }
  171. return 0;
  172. }
  173. int ooh323c_stop_stack_thread(void)
  174. {
  175. if(ooh323c_thread != AST_PTHREADT_NULL)
  176. {
  177. ooStopMonitor();
  178. pthread_join(ooh323c_thread, NULL);
  179. ooh323c_thread = AST_PTHREADT_NULL;
  180. pthread_join(ooh323cmd_thread, NULL);
  181. ooh323cmd_thread = AST_PTHREADT_NULL;
  182. }
  183. return 0;
  184. }
  185. int ooh323c_set_capability
  186. (struct ast_format_cap *cap, int dtmf, int dtmfcodec)
  187. {
  188. int ret = 0, x;
  189. if (gH323Debug) {
  190. ast_verb(0, "\tAdding capabilities to H323 endpoint\n");
  191. }
  192. for(x=0; x<ast_format_cap_count(cap); x++)
  193. {
  194. struct ast_format *format = ast_format_cap_get_format(cap, x);
  195. if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL)
  196. {
  197. if (gH323Debug) {
  198. ast_verb(0, "\tAdding g711 ulaw capability to H323 endpoint\n");
  199. }
  200. ret= ooH323EpAddG711Capability(OO_G711ULAW64K, gtxframes, grxframes,
  201. OORXANDTX, &ooh323c_start_receive_channel,
  202. &ooh323c_start_transmit_channel,
  203. &ooh323c_stop_receive_channel,
  204. &ooh323c_stop_transmit_channel);
  205. }
  206. if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL)
  207. {
  208. if (gH323Debug) {
  209. ast_verb(0, "\tAdding g711 alaw capability to H323 endpoint\n");
  210. }
  211. ret= ooH323EpAddG711Capability(OO_G711ALAW64K, gtxframes, grxframes,
  212. OORXANDTX, &ooh323c_start_receive_channel,
  213. &ooh323c_start_transmit_channel,
  214. &ooh323c_stop_receive_channel,
  215. &ooh323c_stop_transmit_channel);
  216. }
  217. if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL)
  218. {
  219. if (gH323Debug) {
  220. ast_verb(0, "\tAdding g729A capability to H323 endpoint\n");
  221. }
  222. ret = ooH323EpAddG729Capability(OO_G729A, 2, 24,
  223. OORXANDTX, &ooh323c_start_receive_channel,
  224. &ooh323c_start_transmit_channel,
  225. &ooh323c_stop_receive_channel,
  226. &ooh323c_stop_transmit_channel);
  227. if (gH323Debug) {
  228. ast_verb(0, "\tAdding g729 capability to H323 endpoint\n");
  229. }
  230. ret |= ooH323EpAddG729Capability(OO_G729, 2, 24,
  231. OORXANDTX, &ooh323c_start_receive_channel,
  232. &ooh323c_start_transmit_channel,
  233. &ooh323c_stop_receive_channel,
  234. &ooh323c_stop_transmit_channel);
  235. if (gH323Debug) {
  236. ast_verb(0, "\tAdding g729b capability to H323 endpoint\n");
  237. }
  238. ret |= ooH323EpAddG729Capability(OO_G729B, 2, 24,
  239. OORXANDTX, &ooh323c_start_receive_channel,
  240. &ooh323c_start_transmit_channel,
  241. &ooh323c_stop_receive_channel,
  242. &ooh323c_stop_transmit_channel);
  243. }
  244. if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL)
  245. {
  246. if (gH323Debug) {
  247. ast_verb(0, "\tAdding g7231 capability to H323 endpoint\n");
  248. }
  249. ret = ooH323EpAddG7231Capability(OO_G7231, 1, 1, FALSE,
  250. OORXANDTX, &ooh323c_start_receive_channel,
  251. &ooh323c_start_transmit_channel,
  252. &ooh323c_stop_receive_channel,
  253. &ooh323c_stop_transmit_channel);
  254. }
  255. if(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL)
  256. {
  257. if (gH323Debug) {
  258. ast_verb(0, "\tAdding g726 capability to H323 endpoint\n");
  259. }
  260. ret = ooH323EpAddG726Capability(OO_G726, gtxframes, grxframes, FALSE,
  261. OORXANDTX, &ooh323c_start_receive_channel,
  262. &ooh323c_start_transmit_channel,
  263. &ooh323c_stop_receive_channel,
  264. &ooh323c_stop_transmit_channel);
  265. }
  266. if(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL)
  267. {
  268. if (gH323Debug) {
  269. ast_verb(0, "\tAdding g726aal2 capability to H323 endpoint\n");
  270. }
  271. ret = ooH323EpAddG726Capability(OO_G726AAL2, gtxframes, grxframes, FALSE,
  272. OORXANDTX, &ooh323c_start_receive_channel,
  273. &ooh323c_start_transmit_channel,
  274. &ooh323c_stop_receive_channel,
  275. &ooh323c_stop_transmit_channel);
  276. }
  277. if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL)
  278. {
  279. if (gH323Debug) {
  280. ast_verb(0, "\tAdding h263 capability to H323 endpoint\n");
  281. }
  282. ret = ooH323EpAddH263VideoCapability(OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024,
  283. OORXANDTX, &ooh323c_start_receive_channel,
  284. &ooh323c_start_transmit_channel,
  285. &ooh323c_stop_receive_channel,
  286. &ooh323c_stop_transmit_channel);
  287. }
  288. if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL)
  289. {
  290. if (gH323Debug) {
  291. ast_verb(0, "\tAdding gsm capability to H323 endpoint\n");
  292. }
  293. ret = ooH323EpAddGSMCapability(OO_GSMFULLRATE, 4, FALSE, FALSE,
  294. OORXANDTX, &ooh323c_start_receive_channel,
  295. &ooh323c_start_transmit_channel,
  296. &ooh323c_stop_receive_channel,
  297. &ooh323c_stop_transmit_channel);
  298. }
  299. if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL)
  300. {
  301. if (gH323Debug) {
  302. ast_verb(0, "\tAdding speex capability to H323 endpoint\n");
  303. }
  304. ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE,
  305. OORXANDTX, &ooh323c_start_receive_channel,
  306. &ooh323c_start_transmit_channel,
  307. &ooh323c_stop_receive_channel,
  308. &ooh323c_stop_transmit_channel);
  309. }
  310. ao2_ref(format, -1);
  311. }
  312. if(dtmf & H323_DTMF_CISCO)
  313. ret |= ooH323EpEnableDTMFCISCO(0);
  314. if(dtmf & H323_DTMF_RFC2833)
  315. ret |= ooH323EpEnableDTMFRFC2833(0);
  316. else if(dtmf & H323_DTMF_H245ALPHANUMERIC)
  317. ret |= ooH323EpEnableDTMFH245Alphanumeric();
  318. else if(dtmf & H323_DTMF_H245SIGNAL)
  319. ret |= ooH323EpEnableDTMFH245Signal();
  320. return ret;
  321. }
  322. int ooh323c_set_capability_for_call
  323. (ooCallData *call, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
  324. int t38support, int g729onlyA)
  325. {
  326. int ret = 0, x, txframes;
  327. if (gH323Debug) {
  328. ast_verb(0, "\tAdding capabilities to call(%s, %s)\n", call->callType,
  329. call->callToken);
  330. }
  331. if(dtmf & H323_DTMF_CISCO || 1)
  332. ret |= ooCallEnableDTMFCISCO(call,dtmfcodec);
  333. if(dtmf & H323_DTMF_RFC2833 || 1)
  334. ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec);
  335. if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1)
  336. ret |= ooCallEnableDTMFH245Alphanumeric(call);
  337. if(dtmf & H323_DTMF_H245SIGNAL || 1)
  338. ret |= ooCallEnableDTMFH245Signal(call);
  339. if (t38support)
  340. ooCapabilityAddT38Capability(call, OO_T38, OORXANDTX,
  341. &ooh323c_start_receive_datachannel,
  342. &ooh323c_start_transmit_datachannel,
  343. &ooh323c_stop_receive_datachannel,
  344. &ooh323c_stop_transmit_datachannel,
  345. 0);
  346. for(x=0; x<ast_format_cap_count(cap); x++)
  347. {
  348. struct ast_format *format = ast_format_cap_get_format(cap, x);
  349. if(ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL)
  350. {
  351. if (gH323Debug) {
  352. ast_verb(0, "\tAdding g711 ulaw capability to call(%s, %s)\n",
  353. call->callType, call->callToken);
  354. }
  355. txframes = ast_format_cap_get_format_framing(cap, format);
  356. ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes,
  357. txframes, OORXANDTX,
  358. &ooh323c_start_receive_channel,
  359. &ooh323c_start_transmit_channel,
  360. &ooh323c_stop_receive_channel,
  361. &ooh323c_stop_transmit_channel);
  362. }
  363. if(ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL)
  364. {
  365. if (gH323Debug) {
  366. ast_verb(0, "\tAdding g711 alaw capability to call(%s, %s)\n",
  367. call->callType, call->callToken);
  368. }
  369. txframes = ast_format_cap_get_format_framing(cap, format);
  370. ret= ooCallAddG711Capability(call, OO_G711ALAW64K, txframes,
  371. txframes, OORXANDTX,
  372. &ooh323c_start_receive_channel,
  373. &ooh323c_start_transmit_channel,
  374. &ooh323c_stop_receive_channel,
  375. &ooh323c_stop_transmit_channel);
  376. }
  377. if(ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL)
  378. {
  379. if (gH323Debug) {
  380. ast_verb(0, "\tAdding g726 capability to call (%s, %s)\n",
  381. call->callType, call->callToken);
  382. }
  383. txframes = ast_format_cap_get_format_framing(cap, format);
  384. ret = ooCallAddG726Capability(call, OO_G726, txframes, grxframes, FALSE,
  385. OORXANDTX, &ooh323c_start_receive_channel,
  386. &ooh323c_start_transmit_channel,
  387. &ooh323c_stop_receive_channel,
  388. &ooh323c_stop_transmit_channel);
  389. }
  390. if(ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL)
  391. {
  392. if (gH323Debug) {
  393. ast_verb(0, "\tAdding g726aal2 capability to call (%s, %s)\n",
  394. call->callType, call->callToken);
  395. }
  396. txframes = ast_format_cap_get_format_framing(cap, format);
  397. ret = ooCallAddG726Capability(call, OO_G726AAL2, txframes, grxframes, FALSE,
  398. OORXANDTX, &ooh323c_start_receive_channel,
  399. &ooh323c_start_transmit_channel,
  400. &ooh323c_stop_receive_channel,
  401. &ooh323c_stop_transmit_channel);
  402. }
  403. if(ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL)
  404. {
  405. txframes = (ast_format_cap_get_format_framing(cap, format))/10;
  406. if (gH323Debug) {
  407. ast_verb(0, "\tAdding g729A capability to call(%s, %s)\n",
  408. call->callType, call->callToken);
  409. }
  410. ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes,
  411. OORXANDTX, &ooh323c_start_receive_channel,
  412. &ooh323c_start_transmit_channel,
  413. &ooh323c_stop_receive_channel,
  414. &ooh323c_stop_transmit_channel);
  415. if (g729onlyA)
  416. continue;
  417. if (gH323Debug) {
  418. ast_verb(0, "\tAdding g729 capability to call(%s, %s)\n",
  419. call->callType, call->callToken);
  420. }
  421. ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes,
  422. OORXANDTX, &ooh323c_start_receive_channel,
  423. &ooh323c_start_transmit_channel,
  424. &ooh323c_stop_receive_channel,
  425. &ooh323c_stop_transmit_channel);
  426. if (gH323Debug) {
  427. ast_verb(0, "\tAdding g729B capability to call(%s, %s)\n",
  428. call->callType, call->callToken);
  429. }
  430. ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes,
  431. OORXANDTX, &ooh323c_start_receive_channel,
  432. &ooh323c_start_transmit_channel,
  433. &ooh323c_stop_receive_channel,
  434. &ooh323c_stop_transmit_channel);
  435. }
  436. if(ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL)
  437. {
  438. if (gH323Debug) {
  439. ast_verb(0, "\tAdding g7231 capability to call (%s, %s)\n",
  440. call->callType, call->callToken);
  441. }
  442. ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE,
  443. OORXANDTX, &ooh323c_start_receive_channel,
  444. &ooh323c_start_transmit_channel,
  445. &ooh323c_stop_receive_channel,
  446. &ooh323c_stop_transmit_channel);
  447. }
  448. if(ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL)
  449. {
  450. if (gH323Debug) {
  451. ast_verb(0, "\tAdding h263 capability to call (%s, %s)\n",
  452. call->callType, call->callToken);
  453. }
  454. ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024,
  455. OORXANDTX, &ooh323c_start_receive_channel,
  456. &ooh323c_start_transmit_channel,
  457. &ooh323c_stop_receive_channel,
  458. &ooh323c_stop_transmit_channel);
  459. }
  460. if(ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL)
  461. {
  462. if (gH323Debug) {
  463. ast_verb(0, "\tAdding gsm capability to call(%s, %s)\n",
  464. call->callType, call->callToken);
  465. }
  466. ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE,
  467. OORXANDTX, &ooh323c_start_receive_channel,
  468. &ooh323c_start_transmit_channel,
  469. &ooh323c_stop_receive_channel,
  470. &ooh323c_stop_transmit_channel);
  471. }
  472. if(ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL)
  473. {
  474. if (gH323Debug) {
  475. ast_verb(0, "\tAdding Speex capability to call(%s, %s)\n",
  476. call->callType, call->callToken);
  477. }
  478. ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE,
  479. OORXANDTX, &ooh323c_start_receive_channel,
  480. &ooh323c_start_transmit_channel,
  481. &ooh323c_stop_receive_channel,
  482. &ooh323c_stop_transmit_channel);
  483. }
  484. ao2_ref(format, -1);
  485. }
  486. return ret;
  487. }
  488. int ooh323c_set_aliases(ooAliases * aliases)
  489. {
  490. ooAliases *cur = aliases;
  491. while(cur)
  492. {
  493. switch(cur->type)
  494. {
  495. case T_H225AliasAddress_dialedDigits:
  496. ooH323EpAddAliasDialedDigits(cur->value);
  497. break;
  498. case T_H225AliasAddress_h323_ID:
  499. ooH323EpAddAliasH323ID(cur->value);
  500. break;
  501. case T_H225AliasAddress_url_ID:
  502. ooH323EpAddAliasURLID(cur->value);
  503. break;
  504. case T_H225AliasAddress_email_ID:
  505. ooH323EpAddAliasEmailID(cur->value);
  506. break;
  507. default:
  508. ast_debug(1, "Ignoring unknown alias type\n");
  509. }
  510. cur = cur->next;
  511. }
  512. return 1;
  513. }
  514. int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
  515. {
  516. struct ast_format *tmpfmt = NULL;
  517. tmpfmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
  518. if(tmpfmt) {
  519. /* ooh323_set_read_format(call, fmt); */
  520. }else{
  521. ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
  522. call->callToken);
  523. return -1;
  524. }
  525. return 1;
  526. }
  527. int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
  528. {
  529. struct ast_format *tmpfmt = NULL;
  530. tmpfmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
  531. if (tmpfmt) {
  532. if ((ast_format_cmp(tmpfmt, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) ||
  533. (ast_format_cmp(tmpfmt, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL)) {
  534. ooh323_set_write_format(call, tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
  535. } else if (ast_format_cmp(tmpfmt, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
  536. ooh323_set_write_format(call, tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
  537. } else {
  538. ooh323_set_write_format(call, tmpfmt, 0);
  539. }
  540. }else{
  541. ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
  542. call->callToken);
  543. return -1;
  544. }
  545. setup_rtp_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
  546. return 1;
  547. }
  548. int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
  549. {
  550. return 1;
  551. }
  552. int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
  553. {
  554. close_rtp_connection(call);
  555. return 1;
  556. }
  557. int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
  558. {
  559. return 1;
  560. }
  561. int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
  562. {
  563. setup_udptl_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
  564. return 1;
  565. }
  566. int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
  567. {
  568. return 1;
  569. }
  570. int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
  571. {
  572. close_udptl_connection(call);
  573. return 1;
  574. }
  575. struct ast_format *convertH323CapToAsteriskCap(int cap)
  576. {
  577. switch(cap)
  578. {
  579. case OO_G711ULAW64K:
  580. return ast_format_ulaw;
  581. case OO_G711ALAW64K:
  582. return ast_format_alaw;
  583. case OO_GSMFULLRATE:
  584. return ast_format_gsm;
  585. case OO_SPEEX:
  586. return ast_format_speex;
  587. case OO_G729:
  588. return ast_format_g729;
  589. case OO_G729A:
  590. return ast_format_g729;
  591. case OO_G729B:
  592. return ast_format_g729;
  593. case OO_G7231:
  594. return ast_format_g723;
  595. case OO_G726:
  596. return ast_format_g726;
  597. case OO_G726AAL2:
  598. return ast_format_g726_aal2;
  599. case OO_H263VIDEO:
  600. return ast_format_h263;
  601. default:
  602. ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
  603. return NULL;
  604. }
  605. return NULL;
  606. }