2
0

tdm.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /*
  2. * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  3. * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
  4. *
  5. * Version: MPL 1.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License Version
  8. * 1.1 (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. * for the specific language governing rights and limitations under the
  15. * License.
  16. *
  17. * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  18. *
  19. * The Initial Developer of the Original Code is
  20. * Anthony Minessale II <anthm@freeswitch.org>
  21. * Portions created by the Initial Developer are Copyright (C)
  22. * the Initial Developer. All Rights Reserved.
  23. *
  24. * Contributor(s):
  25. *
  26. * Mathieu Rene <mrene@avgs.ca>
  27. *
  28. * tdm.c -- FreeTDM Controllable Channel Module
  29. *
  30. */
  31. #include <switch.h>
  32. #include "freetdm.h"
  33. void ctdm_init(switch_loadable_module_interface_t *module_interface);
  34. /* Parameters */
  35. #define kSPAN_ID "span"
  36. #define kCHAN_ID "chan"
  37. #define kSPAN_NAME "span_name"
  38. #define kPREBUFFER_LEN "prebuffer_len"
  39. #define kECHOCANCEL "echo_cancel"
  40. static struct {
  41. switch_memory_pool_t *pool;
  42. switch_endpoint_interface_t *endpoint_interface;
  43. } ctdm;
  44. typedef struct {
  45. int span_id;
  46. int chan_id;
  47. ftdm_channel_t *ftdm_channel;
  48. switch_core_session_t *session;
  49. switch_codec_t read_codec, write_codec;
  50. switch_frame_t read_frame;
  51. int prebuffer_len;
  52. unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
  53. } ctdm_private_t;
  54. static switch_status_t channel_on_init(switch_core_session_t *session);
  55. static switch_status_t channel_on_destroy(switch_core_session_t *session);
  56. static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
  57. switch_caller_profile_t *outbound_profile,
  58. switch_core_session_t **new_session,
  59. switch_memory_pool_t **pool,
  60. switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
  61. static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
  62. static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
  63. static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg);
  64. static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event);
  65. static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf);
  66. static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span);
  67. switch_state_handler_table_t ctdm_state_handlers = {
  68. .on_init = channel_on_init,
  69. .on_destroy = channel_on_destroy
  70. };
  71. switch_io_routines_t ctdm_io_routines = {
  72. .send_dtmf = channel_send_dtmf,
  73. .outgoing_channel = channel_outgoing_channel,
  74. .read_frame = channel_read_frame,
  75. .write_frame = channel_write_frame,
  76. .receive_message = channel_receive_message,
  77. .receive_event = channel_receive_event
  78. };
  79. static void ctdm_report_alarms(ftdm_channel_t *channel)
  80. {
  81. switch_event_t *event = NULL;
  82. ftdm_alarm_flag_t alarmflag = 0;
  83. if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
  84. ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
  85. return;
  86. }
  87. if (ftdm_channel_get_alarms(channel, &alarmflag) != FTDM_SUCCESS) {
  88. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve alarms %s:%d\n", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
  89. return;
  90. }
  91. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(channel));
  92. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(channel));
  93. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(channel));
  94. if (alarmflag) {
  95. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
  96. } else {
  97. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
  98. }
  99. if (alarmflag & FTDM_ALARM_RED) {
  100. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
  101. }
  102. if (alarmflag & FTDM_ALARM_YELLOW) {
  103. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
  104. }
  105. if (alarmflag & FTDM_ALARM_RAI) {
  106. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
  107. }
  108. if (alarmflag & FTDM_ALARM_BLUE) {
  109. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
  110. }
  111. if (alarmflag & FTDM_ALARM_AIS) {
  112. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
  113. }
  114. if (alarmflag & FTDM_ALARM_GENERAL) {
  115. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
  116. }
  117. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reporting [%s] alarms for %s:%d\n",
  118. (alarmflag?"ftdm-alarm-trap":"ftdm-alarm-clear"), ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
  119. switch_event_fire(&event);
  120. return;
  121. }
  122. static ftdm_channel_t *ctdm_get_channel_from_event(switch_event_t *event, ftdm_span_t *span)
  123. {
  124. uint32_t chan_id = 0;
  125. const char *chan_number = NULL;
  126. chan_number = switch_event_get_header(event, "chan-number");
  127. if (zstr(chan_number)) {
  128. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channel number specified\n");
  129. return NULL;
  130. }
  131. chan_id = atoi(chan_number);
  132. if (!chan_id) {
  133. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid channel number:%s\n", chan_number);
  134. return NULL;
  135. }
  136. return ftdm_span_get_channel_ph(span, chan_id);
  137. }
  138. static void ctdm_event_handler(switch_event_t *event)
  139. {
  140. ftdm_status_t status = FTDM_FAIL;
  141. switch(event->event_id) {
  142. case SWITCH_EVENT_TRAP:
  143. {
  144. ftdm_span_t *span = NULL;
  145. ftdm_channel_t *channel = NULL;
  146. const char *span_name = NULL;
  147. const char *cond = switch_event_get_header(event, "condition");
  148. const char *command = switch_event_get_header(event, "command");
  149. if (zstr(cond)) {
  150. return;
  151. }
  152. span_name = switch_event_get_header(event, "span-name");
  153. if (ftdm_span_find_by_name(span_name, &span) != FTDM_SUCCESS) {
  154. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
  155. return;
  156. }
  157. if (!strcmp(cond, "mg-tdm-prepare")) {
  158. status = ctdm_span_prepare(span);
  159. if (status == FTDM_SUCCESS) {
  160. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s:prepared successfully\n", span_name);
  161. } else if (status != FTDM_EINVAL) {
  162. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:Failed to prepare span\n", span_name);
  163. }
  164. } else if (!strcmp(cond, "mg-tdm-check")) {
  165. channel = ctdm_get_channel_from_event(event, span);
  166. if (!channel) {
  167. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n");
  168. return;
  169. }
  170. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Requesting alarm status for %s:%d\n",
  171. ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
  172. ctdm_report_alarms(channel);
  173. } else if (!strcmp(cond, "mg-tdm-dtmfremoval")) {
  174. uint8_t enable = 0;
  175. channel = ctdm_get_channel_from_event(event, span);
  176. if (!channel) {
  177. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n");
  178. return;
  179. }
  180. if (zstr(command)) {
  181. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:No command specified for mg-tdm-dtmfremoval\n", span_name);
  182. return;
  183. }
  184. if (!strcmp(command, "enable")) {
  185. enable = 1;
  186. }
  187. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s DTMF-removal for %s:%d\n",
  188. enable ? "Enabling" : "Disabling", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
  189. ftdm_channel_command(channel, enable ? FTDM_COMMAND_ENABLE_DTMF_REMOVAL : FTDM_COMMAND_DISABLE_DTMF_REMOVAL, 0);
  190. }
  191. }
  192. break;
  193. default:
  194. break;
  195. }
  196. return;
  197. }
  198. void ctdm_init(switch_loadable_module_interface_t *module_interface)
  199. {
  200. switch_endpoint_interface_t *endpoint_interface;
  201. ctdm.pool = module_interface->pool;
  202. endpoint_interface = switch_loadable_module_create_interface(module_interface, SWITCH_ENDPOINT_INTERFACE);
  203. endpoint_interface->interface_name = "tdm";
  204. endpoint_interface->io_routines = &ctdm_io_routines;
  205. endpoint_interface->state_handler = &ctdm_state_handlers;
  206. ctdm.endpoint_interface = endpoint_interface;
  207. switch_event_bind("mod_freetdm", SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, ctdm_event_handler, NULL);
  208. }
  209. static FIO_SIGNAL_CB_FUNCTION(on_signal_cb)
  210. {
  211. uint32_t chanid, spanid;
  212. switch_event_t *event = NULL;
  213. ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
  214. chanid = ftdm_channel_get_id(sigmsg->channel);
  215. spanid = ftdm_channel_get_span_id(sigmsg->channel);
  216. switch(sigmsg->event_id) {
  217. case FTDM_SIGEVENT_ALARM_CLEAR:
  218. case FTDM_SIGEVENT_ALARM_TRAP:
  219. {
  220. if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) {
  221. ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n");
  222. return FTDM_FAIL;
  223. }
  224. if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
  225. ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
  226. return FTDM_FAIL;
  227. }
  228. if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) {
  229. ftdm_log(FTDM_LOG_NOTICE, "Alarm cleared on channel %d:%d\n", spanid, chanid);
  230. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
  231. } else {
  232. ftdm_log(FTDM_LOG_NOTICE, "Alarm raised on channel %d:%d\n", spanid, chanid);
  233. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
  234. }
  235. }
  236. break;
  237. default:
  238. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unhandled event %d\n", sigmsg->event_id);
  239. break;
  240. }
  241. if (event) {
  242. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
  243. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
  244. switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
  245. if (alarmbits & FTDM_ALARM_RED) {
  246. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
  247. }
  248. if (alarmbits & FTDM_ALARM_YELLOW) {
  249. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
  250. }
  251. if (alarmbits & FTDM_ALARM_RAI) {
  252. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
  253. }
  254. if (alarmbits & FTDM_ALARM_BLUE) {
  255. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
  256. }
  257. if (alarmbits & FTDM_ALARM_AIS) {
  258. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
  259. }
  260. if (alarmbits & FTDM_ALARM_GENERAL) {
  261. switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
  262. }
  263. switch_event_fire(&event);
  264. }
  265. return FTDM_SUCCESS;
  266. }
  267. static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span)
  268. {
  269. if (ftdm_span_register_signal_cb(span, on_signal_cb) != FTDM_SUCCESS) {
  270. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register signal CB\n");
  271. return FTDM_FAIL;
  272. }
  273. return ftdm_span_start(span);
  274. }
  275. static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
  276. switch_caller_profile_t *outbound_profile,
  277. switch_core_session_t **new_session,
  278. switch_memory_pool_t **pool,
  279. switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
  280. {
  281. const char *szchanid = switch_event_get_header(var_event, kCHAN_ID),
  282. *span_name = switch_event_get_header(var_event, kSPAN_NAME),
  283. *szprebuffer_len = switch_event_get_header(var_event, kPREBUFFER_LEN);
  284. int chan_id;
  285. int span_id;
  286. switch_caller_profile_t *caller_profile;
  287. ftdm_span_t *span;
  288. ftdm_channel_t *chan;
  289. switch_channel_t *channel;
  290. char name[128];
  291. const char *dname;
  292. ftdm_codec_t codec;
  293. uint32_t interval;
  294. ctdm_private_t *tech_pvt = NULL;
  295. if (zstr(szchanid) || zstr(span_name)) {
  296. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Both ["kSPAN_ID"] and ["kCHAN_ID"] have to be set.\n");
  297. goto fail;
  298. }
  299. chan_id = atoi(szchanid);
  300. if (ftdm_span_find_by_name(span_name, &span) == FTDM_SUCCESS) {
  301. span_id = ftdm_span_get_id(span);
  302. } else {
  303. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
  304. goto fail;
  305. }
  306. if (!(*new_session = switch_core_session_request(ctdm.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) {
  307. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n");
  308. goto fail;
  309. }
  310. channel = switch_core_session_get_channel(*new_session);
  311. if (ftdm_channel_open_ph(span_id, chan_id, &chan) != FTDM_SUCCESS) {
  312. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open span or channel.\n");
  313. goto fail;
  314. }
  315. switch_channel_set_flag(channel, CF_AUDIO);
  316. span = ftdm_channel_get_span(chan);
  317. tech_pvt = switch_core_session_alloc(*new_session, sizeof *tech_pvt);
  318. tech_pvt->chan_id = chan_id;
  319. tech_pvt->span_id = span_id;
  320. tech_pvt->ftdm_channel = chan;
  321. tech_pvt->session = *new_session;
  322. tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
  323. tech_pvt->read_frame.data = tech_pvt->databuf;
  324. tech_pvt->prebuffer_len = zstr(szprebuffer_len) ? 0 : atoi(szprebuffer_len);
  325. switch_core_session_set_private(*new_session, tech_pvt);
  326. caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
  327. switch_channel_set_caller_profile(channel, caller_profile);
  328. snprintf(name, sizeof(name), "tdm/%d:%d", span_id, chan_id);
  329. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
  330. switch_channel_set_name(channel, name);
  331. switch_channel_set_state(channel, CS_INIT);
  332. if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_CODEC, &codec)) {
  333. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
  334. return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
  335. }
  336. if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval)) {
  337. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n");
  338. return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
  339. }
  340. if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
  341. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
  342. return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
  343. }
  344. if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
  345. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to set enable echo cancellation.\n");
  346. }
  347. switch(codec) {
  348. case FTDM_CODEC_ULAW:
  349. {
  350. dname = "PCMU";
  351. }
  352. break;
  353. case FTDM_CODEC_ALAW:
  354. {
  355. dname = "PCMA";
  356. }
  357. break;
  358. case FTDM_CODEC_SLIN:
  359. {
  360. dname = "L16";
  361. }
  362. break;
  363. default:
  364. {
  365. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec);
  366. goto fail;
  367. }
  368. }
  369. if (switch_core_codec_init(&tech_pvt->read_codec,
  370. dname,
  371. NULL,
  372. NULL,
  373. 8000,
  374. interval,
  375. 1,
  376. SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
  377. NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
  378. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
  379. goto fail;
  380. } else {
  381. if (switch_core_codec_init(&tech_pvt->write_codec,
  382. dname,
  383. NULL,
  384. NULL,
  385. 8000,
  386. interval,
  387. 1,
  388. SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
  389. NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
  390. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
  391. switch_core_codec_destroy(&tech_pvt->read_codec);
  392. goto fail;
  393. }
  394. }
  395. if (switch_core_session_set_read_codec(*new_session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
  396. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
  397. goto fail;
  398. }
  399. if (switch_core_session_set_write_codec(*new_session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
  400. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");
  401. }
  402. if (switch_core_session_thread_launch(*new_session) != SWITCH_STATUS_SUCCESS) {
  403. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't start session thread.\n");
  404. goto fail;
  405. }
  406. switch_channel_mark_answered(channel);
  407. return SWITCH_CAUSE_SUCCESS;
  408. fail:
  409. if (tech_pvt) {
  410. if (tech_pvt->ftdm_channel) {
  411. ftdm_channel_close(&tech_pvt->ftdm_channel);
  412. }
  413. if (tech_pvt->read_codec.implementation) {
  414. switch_core_codec_destroy(&tech_pvt->read_codec);
  415. }
  416. if (tech_pvt->write_codec.implementation) {
  417. switch_core_codec_destroy(&tech_pvt->write_codec);
  418. }
  419. }
  420. if (*new_session) {
  421. switch_core_session_destroy(new_session);
  422. }
  423. return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
  424. }
  425. static switch_status_t channel_on_init(switch_core_session_t *session)
  426. {
  427. switch_channel_t *channel = switch_core_session_get_channel(session);
  428. switch_channel_set_state(channel, CS_CONSUME_MEDIA);
  429. return SWITCH_STATUS_SUCCESS;
  430. }
  431. static switch_status_t channel_on_destroy(switch_core_session_t *session)
  432. {
  433. ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
  434. if ((tech_pvt = switch_core_session_get_private(session))) {
  435. if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
  436. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to enable echo cancellation.\n");
  437. }
  438. if (tech_pvt->read_codec.implementation) {
  439. switch_core_codec_destroy(&tech_pvt->read_codec);
  440. }
  441. if (tech_pvt->write_codec.implementation) {
  442. switch_core_codec_destroy(&tech_pvt->write_codec);
  443. }
  444. switch_core_session_unset_read_codec(session);
  445. switch_core_session_unset_write_codec(session);
  446. ftdm_channel_close(&tech_pvt->ftdm_channel);
  447. }
  448. return SWITCH_STATUS_SUCCESS;
  449. }
  450. static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
  451. {
  452. ftdm_wait_flag_t wflags = FTDM_READ;
  453. ftdm_status_t status;
  454. ctdm_private_t *tech_pvt;
  455. const char *name;
  456. switch_channel_t *channel;
  457. int chunk;
  458. uint32_t span_id, chan_id;
  459. ftdm_size_t len;
  460. char dtmf[128] = "";
  461. channel = switch_core_session_get_channel(session);
  462. assert(channel != NULL);
  463. tech_pvt = switch_core_session_get_private(session);
  464. assert(tech_pvt != NULL);
  465. name = switch_channel_get_name(channel);
  466. top:
  467. wflags = FTDM_READ;
  468. chunk = ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 2;
  469. status = ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, chunk);
  470. span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel);
  471. chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel);
  472. if (status == FTDM_FAIL) {
  473. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
  474. goto fail;
  475. }
  476. if (status == FTDM_TIMEOUT) {
  477. goto top;
  478. }
  479. if (!(wflags & FTDM_READ)) {
  480. goto top;
  481. }
  482. len = tech_pvt->read_frame.buflen;
  483. if (ftdm_channel_read(tech_pvt->ftdm_channel, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
  484. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
  485. }
  486. *frame = &tech_pvt->read_frame;
  487. tech_pvt->read_frame.datalen = (uint32_t)len;
  488. tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen;
  489. tech_pvt->read_frame.codec = &tech_pvt->read_codec;
  490. if (ftdm_channel_get_codec(tech_pvt->ftdm_channel) == FTDM_CODEC_SLIN) {
  491. tech_pvt->read_frame.samples /= 2;
  492. }
  493. while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdm_channel, dtmf, sizeof(dtmf))) {
  494. switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) };
  495. char *p;
  496. for (p = dtmf; p && *p; p++) {
  497. if (is_dtmf(*p)) {
  498. _dtmf.digit = *p;
  499. ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id);
  500. switch_channel_queue_dtmf(channel, &_dtmf);
  501. }
  502. }
  503. }
  504. return SWITCH_STATUS_SUCCESS;
  505. fail:
  506. return SWITCH_STATUS_GENERR;
  507. }
  508. static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
  509. {
  510. ftdm_wait_flag_t wflags = FTDM_WRITE;
  511. ctdm_private_t *tech_pvt;
  512. const char *name;
  513. switch_channel_t *channel;
  514. uint32_t span_id, chan_id;
  515. ftdm_size_t len;
  516. unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
  517. channel = switch_core_session_get_channel(session);
  518. assert(channel != NULL);
  519. tech_pvt = switch_core_session_get_private(session);
  520. assert(tech_pvt != NULL);
  521. span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel);
  522. chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel);
  523. name = switch_channel_get_name(channel);
  524. if (switch_test_flag(frame, SFF_CNG)) {
  525. frame->data = data;
  526. frame->buflen = sizeof(data);
  527. if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) {
  528. goto fail;
  529. }
  530. memset(data, 255, frame->datalen);
  531. }
  532. wflags = FTDM_WRITE;
  533. ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 10);
  534. if (!(wflags & FTDM_WRITE)) {
  535. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
  536. return SWITCH_STATUS_SUCCESS;
  537. }
  538. len = frame->datalen;
  539. if (ftdm_channel_write(tech_pvt->ftdm_channel, frame->data, frame->buflen, &len) != FTDM_SUCCESS) {
  540. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id);
  541. }
  542. return SWITCH_STATUS_SUCCESS;
  543. fail:
  544. return SWITCH_STATUS_GENERR;
  545. }
  546. static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
  547. {
  548. ctdm_private_t *tech_pvt = NULL;
  549. char tmp[2] = "";
  550. tech_pvt = switch_core_session_get_private(session);
  551. assert(tech_pvt != NULL);
  552. tmp[0] = dtmf->digit;
  553. ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SEND_DTMF, tmp);
  554. return SWITCH_STATUS_SUCCESS;
  555. }
  556. static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
  557. {
  558. return SWITCH_STATUS_SUCCESS;
  559. }
  560. static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
  561. {
  562. const char *command = switch_event_get_header(event, "command");
  563. ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
  564. if (!zstr(command)) {
  565. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received %s command \n",command);
  566. if (!strcasecmp(command, kPREBUFFER_LEN)) {
  567. const char *szval = switch_event_get_header(event, kPREBUFFER_LEN);
  568. int val = !zstr(szval) ? atoi(szval) : 0;
  569. if (tech_pvt->prebuffer_len == val) {
  570. tech_pvt->prebuffer_len = val;
  571. if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
  572. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
  573. return SWITCH_STATUS_GENERR;
  574. }
  575. }
  576. } else if (!strcasecmp(command, kECHOCANCEL)) {
  577. const char *szval = switch_event_get_header(event, kECHOCANCEL);
  578. int enabled = !!switch_true(szval);
  579. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM sending echo cancel [%s] command \n",enabled ? "enable" : "disable");
  580. if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, enabled ? FTDM_COMMAND_ENABLE_ECHOCANCEL : FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL)) {
  581. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to %s echo cancellation.\n", enabled ? "enable" : "disable");
  582. }
  583. } else {
  584. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received unknown command [%s] \n",command);
  585. }
  586. }
  587. return SWITCH_STATUS_SUCCESS;
  588. }