app_fax.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Simple fax applications
  5. *
  6. * 2007-2008, Dmitry Andrianov <asterisk@dima.spb.ru>
  7. *
  8. * Code based on original implementation by Steve Underwood <steveu@coppice.org>
  9. *
  10. * This program is free software, distributed under the terms of
  11. * the GNU General Public License
  12. *
  13. */
  14. /*** MODULEINFO
  15. <defaultenabled>no</defaultenabled>
  16. <depend>spandsp</depend>
  17. <conflict>res_fax</conflict>
  18. <support_level>extended</support_level>
  19. ***/
  20. #include "asterisk.h"
  21. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <inttypes.h>
  26. #include <pthread.h>
  27. #include <errno.h>
  28. #include <tiffio.h>
  29. #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
  30. #include <spandsp.h>
  31. #include <spandsp/version.h>
  32. #include "asterisk/lock.h"
  33. #include "asterisk/file.h"
  34. #include "asterisk/logger.h"
  35. #include "asterisk/channel.h"
  36. #include "asterisk/pbx.h"
  37. #include "asterisk/app.h"
  38. #include "asterisk/dsp.h"
  39. #include "asterisk/module.h"
  40. #include "asterisk/stasis.h"
  41. #include "asterisk/stasis_channels.h"
  42. /*** DOCUMENTATION
  43. <application name="SendFAX" language="en_US" module="app_fax">
  44. <synopsis>
  45. Send a Fax
  46. </synopsis>
  47. <syntax>
  48. <parameter name="filename" required="true">
  49. <para>Filename of TIFF file to fax</para>
  50. </parameter>
  51. <parameter name="a" required="false">
  52. <para>Makes the application behave as the answering machine</para>
  53. <para>(Default behavior is as calling machine)</para>
  54. </parameter>
  55. </syntax>
  56. <description>
  57. <para>Send a given TIFF file to the channel as a FAX.</para>
  58. <para>This application sets the following channel variables:</para>
  59. <variablelist>
  60. <variable name="LOCALSTATIONID">
  61. <para>To identify itself to the remote end</para>
  62. </variable>
  63. <variable name="LOCALHEADERINFO">
  64. <para>To generate a header line on each page</para>
  65. </variable>
  66. <variable name="FAXSTATUS">
  67. <value name="SUCCESS"/>
  68. <value name="FAILED"/>
  69. </variable>
  70. <variable name="FAXERROR">
  71. <para>Cause of failure</para>
  72. </variable>
  73. <variable name="REMOTESTATIONID">
  74. <para>The CSID of the remote side</para>
  75. </variable>
  76. <variable name="FAXPAGES">
  77. <para>Number of pages sent</para>
  78. </variable>
  79. <variable name="FAXBITRATE">
  80. <para>Transmission rate</para>
  81. </variable>
  82. <variable name="FAXRESOLUTION">
  83. <para>Resolution of sent fax</para>
  84. </variable>
  85. </variablelist>
  86. </description>
  87. </application>
  88. <application name="ReceiveFAX" language="en_US" module="app_fax">
  89. <synopsis>
  90. Receive a Fax
  91. </synopsis>
  92. <syntax>
  93. <parameter name="filename" required="true">
  94. <para>Filename of TIFF file save incoming fax</para>
  95. </parameter>
  96. <parameter name="c" required="false">
  97. <para>Makes the application behave as the calling machine</para>
  98. <para>(Default behavior is as answering machine)</para>
  99. </parameter>
  100. </syntax>
  101. <description>
  102. <para>Receives a FAX from the channel into the given filename
  103. overwriting the file if it already exists.</para>
  104. <para>File created will be in TIFF format.</para>
  105. <para>This application sets the following channel variables:</para>
  106. <variablelist>
  107. <variable name="LOCALSTATIONID">
  108. <para>To identify itself to the remote end</para>
  109. </variable>
  110. <variable name="LOCALHEADERINFO">
  111. <para>To generate a header line on each page</para>
  112. </variable>
  113. <variable name="FAXSTATUS">
  114. <value name="SUCCESS"/>
  115. <value name="FAILED"/>
  116. </variable>
  117. <variable name="FAXERROR">
  118. <para>Cause of failure</para>
  119. </variable>
  120. <variable name="REMOTESTATIONID">
  121. <para>The CSID of the remote side</para>
  122. </variable>
  123. <variable name="FAXPAGES">
  124. <para>Number of pages sent</para>
  125. </variable>
  126. <variable name="FAXBITRATE">
  127. <para>Transmission rate</para>
  128. </variable>
  129. <variable name="FAXRESOLUTION">
  130. <para>Resolution of sent fax</para>
  131. </variable>
  132. </variablelist>
  133. </description>
  134. </application>
  135. ***/
  136. static const char app_sndfax_name[] = "SendFAX";
  137. static const char app_rcvfax_name[] = "ReceiveFAX";
  138. #define MAX_SAMPLES 240
  139. /* Watchdog. I have seen situations when remote fax disconnects (because of poor line
  140. quality) while SpanDSP continues staying in T30_STATE_IV_CTC state forever.
  141. To avoid this, we terminate when we see that T30 state does not change for 5 minutes.
  142. We also terminate application when more than 30 minutes passed regardless of
  143. state changes. This is just a precaution measure - no fax should take that long */
  144. #define WATCHDOG_TOTAL_TIMEOUT 30 * 60
  145. #define WATCHDOG_STATE_TIMEOUT 5 * 60
  146. typedef struct {
  147. struct ast_channel *chan;
  148. enum ast_t38_state t38state; /* T38 state of the channel */
  149. int direction; /* Fax direction: 0 - receiving, 1 - sending */
  150. int caller_mode;
  151. char *file_name;
  152. struct ast_control_t38_parameters t38parameters;
  153. volatile int finished;
  154. } fax_session;
  155. static void span_message(int level, const char *msg)
  156. {
  157. if (level == SPAN_LOG_ERROR) {
  158. ast_log(LOG_ERROR, "%s", msg);
  159. } else if (level == SPAN_LOG_WARNING) {
  160. ast_log(LOG_WARNING, "%s", msg);
  161. } else {
  162. ast_debug(1, "%s", msg);
  163. }
  164. }
  165. static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
  166. {
  167. struct ast_channel *chan = (struct ast_channel *) user_data;
  168. struct ast_frame outf = {
  169. .frametype = AST_FRAME_MODEM,
  170. .subclass.integer = AST_MODEM_T38,
  171. .src = __FUNCTION__,
  172. };
  173. /* TODO: Asterisk does not provide means of resending the same packet multiple
  174. times so count is ignored at the moment */
  175. AST_FRAME_SET_BUFFER(&outf, buf, 0, len);
  176. if (ast_write(chan, &outf) < 0) {
  177. ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
  178. return -1;
  179. }
  180. return 0;
  181. }
  182. static void phase_e_handler(t30_state_t *f, void *user_data, int result)
  183. {
  184. RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
  185. RAII_VAR(struct ast_json *, json_filenames, NULL, ast_json_unref);
  186. RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
  187. const char *local_ident;
  188. const char *far_ident;
  189. char buf[20];
  190. fax_session *s = (fax_session *) user_data;
  191. t30_stats_t stat;
  192. int pages_transferred;
  193. ast_debug(1, "Fax phase E handler. result=%d\n", result);
  194. t30_get_transfer_statistics(f, &stat);
  195. s = (fax_session *) user_data;
  196. if (result != T30_ERR_OK) {
  197. s->finished = -1;
  198. /* FAXSTATUS is already set to FAILED */
  199. pbx_builtin_setvar_helper(s->chan, "FAXERROR", t30_completion_code_to_str(result));
  200. ast_log(LOG_WARNING, "Error transmitting fax. result=%d: %s.\n", result, t30_completion_code_to_str(result));
  201. return;
  202. }
  203. s->finished = 1;
  204. local_ident = S_OR(t30_get_tx_ident(f), "");
  205. far_ident = S_OR(t30_get_rx_ident(f), "");
  206. pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "SUCCESS");
  207. pbx_builtin_setvar_helper(s->chan, "FAXERROR", NULL);
  208. pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", far_ident);
  209. #if SPANDSP_RELEASE_DATE >= 20090220
  210. pages_transferred = (s->direction) ? stat.pages_tx : stat.pages_rx;
  211. #else
  212. pages_transferred = stat.pages_transferred;
  213. #endif
  214. snprintf(buf, sizeof(buf), "%d", pages_transferred);
  215. pbx_builtin_setvar_helper(s->chan, "FAXPAGES", buf);
  216. snprintf(buf, sizeof(buf), "%d", stat.y_resolution);
  217. pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", buf);
  218. snprintf(buf, sizeof(buf), "%d", stat.bit_rate);
  219. pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", buf);
  220. ast_debug(1, "Fax transmitted successfully.\n");
  221. ast_debug(1, " Remote station ID: %s\n", far_ident);
  222. ast_debug(1, " Pages transferred: %d\n", pages_transferred);
  223. ast_debug(1, " Image resolution: %d x %d\n", stat.x_resolution, stat.y_resolution);
  224. ast_debug(1, " Transfer Rate: %d\n", stat.bit_rate);
  225. json_filenames = ast_json_pack("[s]", s->file_name);
  226. if (!json_filenames) {
  227. return;
  228. }
  229. ast_json_ref(json_filenames);
  230. json_object = ast_json_pack("{s: s, s: s, s: s, s: i, s: i, s: i, s: o}",
  231. "type", s->direction ? "send" : "receive",
  232. "remote_station_id", far_ident,
  233. "local_station_id", local_ident,
  234. "fax_pages", pages_transferred,
  235. "fax_resolution", stat.y_resolution,
  236. "fax_bitrate", stat.bit_rate,
  237. "filenames", json_filenames);
  238. message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(s->chan), ast_channel_fax_type(), json_object);
  239. if (!message) {
  240. return;
  241. }
  242. stasis_publish(ast_channel_topic(s->chan), message);
  243. }
  244. /* === Helper functions to configure fax === */
  245. /* Setup SPAN logging according to Asterisk debug level */
  246. static int set_logging(logging_state_t *state)
  247. {
  248. int level = SPAN_LOG_WARNING + option_debug;
  249. span_log_set_message_handler(state, span_message);
  250. span_log_set_level(state, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | level);
  251. return 0;
  252. }
  253. static void set_local_info(t30_state_t *state, fax_session *s)
  254. {
  255. const char *x;
  256. x = pbx_builtin_getvar_helper(s->chan, "LOCALSTATIONID");
  257. if (!ast_strlen_zero(x))
  258. t30_set_tx_ident(state, x);
  259. x = pbx_builtin_getvar_helper(s->chan, "LOCALHEADERINFO");
  260. if (!ast_strlen_zero(x))
  261. t30_set_tx_page_header_info(state, x);
  262. }
  263. static void set_file(t30_state_t *state, fax_session *s)
  264. {
  265. if (s->direction)
  266. t30_set_tx_file(state, s->file_name, -1, -1);
  267. else
  268. t30_set_rx_file(state, s->file_name, -1);
  269. }
  270. static void set_ecm(t30_state_t *state, int ecm)
  271. {
  272. t30_set_ecm_capability(state, ecm);
  273. t30_set_supported_compressions(state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
  274. }
  275. /* === Generator === */
  276. /* This function is only needed to return passed params so
  277. generator_activate will save it to channel's generatordata */
  278. static void *fax_generator_alloc(struct ast_channel *chan, void *params)
  279. {
  280. return params;
  281. }
  282. static int fax_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
  283. {
  284. fax_state_t *fax = (fax_state_t*) data;
  285. uint8_t buffer[AST_FRIENDLY_OFFSET + MAX_SAMPLES * sizeof(uint16_t)];
  286. int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
  287. struct ast_frame outf = {
  288. .frametype = AST_FRAME_VOICE,
  289. .src = __FUNCTION__,
  290. };
  291. ast_format_set(&outf.subclass.format, AST_FORMAT_SLINEAR, 0);
  292. if (samples > MAX_SAMPLES) {
  293. ast_log(LOG_WARNING, "Only generating %d samples, where %d requested\n", MAX_SAMPLES, samples);
  294. samples = MAX_SAMPLES;
  295. }
  296. if ((len = fax_tx(fax, buf, samples)) > 0) {
  297. outf.samples = len;
  298. AST_FRAME_SET_BUFFER(&outf, buffer, AST_FRIENDLY_OFFSET, len * sizeof(int16_t));
  299. if (ast_write(chan, &outf) < 0) {
  300. ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", ast_channel_name(chan), strerror(errno));
  301. return -1;
  302. }
  303. }
  304. return 0;
  305. }
  306. static struct ast_generator generator = {
  307. alloc: fax_generator_alloc,
  308. generate: fax_generator_generate,
  309. };
  310. /* === Transmission === */
  311. static int transmit_audio(fax_session *s)
  312. {
  313. int res = -1;
  314. struct ast_format original_read_fmt;
  315. struct ast_format original_write_fmt;
  316. fax_state_t fax;
  317. t30_state_t *t30state;
  318. struct ast_frame *inf = NULL;
  319. int last_state = 0;
  320. struct timeval now, start, state_change;
  321. enum ast_t38_state t38_state;
  322. struct ast_control_t38_parameters t38_parameters = { .version = 0,
  323. .max_ifp = 800,
  324. .rate = AST_T38_RATE_14400,
  325. .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
  326. .fill_bit_removal = 1,
  327. /*
  328. * spandsp has API calls to support MMR and JBIG transcoding, but they aren't
  329. * implemented quite yet... so don't offer them to the remote endpoint
  330. * .transcoding_mmr = 1,
  331. * .transcoding_jbig = 1,
  332. */
  333. };
  334. ast_format_clear(&original_read_fmt);
  335. ast_format_clear(&original_write_fmt);
  336. /* if in called party mode, try to use T.38 */
  337. if (s->caller_mode == FALSE) {
  338. /* check if we are already in T.38 mode (unlikely), or if we can request
  339. * a switch... if so, request it now and wait for the result, rather
  340. * than starting an audio FAX session that will have to be cancelled
  341. */
  342. if ((t38_state = ast_channel_get_t38_state(s->chan)) == T38_STATE_NEGOTIATED) {
  343. return 1;
  344. } else if ((t38_state != T38_STATE_UNAVAILABLE) &&
  345. (t38_parameters.request_response = AST_T38_REQUEST_NEGOTIATE,
  346. (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0))) {
  347. /* wait up to five seconds for negotiation to complete */
  348. unsigned int timeout = 5000;
  349. int ms;
  350. ast_debug(1, "Negotiating T.38 for receive on %s\n", ast_channel_name(s->chan));
  351. while (timeout > 0) {
  352. ms = ast_waitfor(s->chan, 1000);
  353. if (ms < 0) {
  354. ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(s->chan));
  355. return -1;
  356. }
  357. if (!ms) {
  358. /* nothing happened */
  359. if (timeout > 0) {
  360. timeout -= 1000;
  361. continue;
  362. } else {
  363. ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 negotiation.\n", ast_channel_name(s->chan));
  364. break;
  365. }
  366. }
  367. if (!(inf = ast_read(s->chan))) {
  368. return -1;
  369. }
  370. if ((inf->frametype == AST_FRAME_CONTROL) &&
  371. (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
  372. (inf->datalen == sizeof(t38_parameters))) {
  373. struct ast_control_t38_parameters *parameters = inf->data.ptr;
  374. switch (parameters->request_response) {
  375. case AST_T38_NEGOTIATED:
  376. ast_debug(1, "Negotiated T.38 for receive on %s\n", ast_channel_name(s->chan));
  377. res = 1;
  378. break;
  379. case AST_T38_REFUSED:
  380. ast_log(LOG_WARNING, "channel '%s' refused to negotiate T.38\n", ast_channel_name(s->chan));
  381. break;
  382. default:
  383. ast_log(LOG_ERROR, "channel '%s' failed to negotiate T.38\n", ast_channel_name(s->chan));
  384. break;
  385. }
  386. ast_frfree(inf);
  387. if (res == 1) {
  388. return 1;
  389. } else {
  390. break;
  391. }
  392. }
  393. ast_frfree(inf);
  394. }
  395. }
  396. }
  397. #if SPANDSP_RELEASE_DATE >= 20080725
  398. /* for spandsp shaphots 0.0.6 and higher */
  399. t30state = &fax.t30;
  400. #else
  401. /* for spandsp release 0.0.5 */
  402. t30state = &fax.t30_state;
  403. #endif
  404. ast_format_copy(&original_read_fmt, ast_channel_readformat(s->chan));
  405. if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
  406. res = ast_set_read_format_by_id(s->chan, AST_FORMAT_SLINEAR);
  407. if (res < 0) {
  408. ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
  409. goto done;
  410. }
  411. }
  412. ast_format_copy(&original_write_fmt, ast_channel_writeformat(s->chan));
  413. if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
  414. res = ast_set_write_format_by_id(s->chan, AST_FORMAT_SLINEAR);
  415. if (res < 0) {
  416. ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
  417. goto done;
  418. }
  419. }
  420. /* Initialize T30 terminal */
  421. fax_init(&fax, s->caller_mode);
  422. /* Setup logging */
  423. set_logging(&fax.logging);
  424. set_logging(&t30state->logging);
  425. /* Configure terminal */
  426. set_local_info(t30state, s);
  427. set_file(t30state, s);
  428. set_ecm(t30state, TRUE);
  429. fax_set_transmit_on_idle(&fax, TRUE);
  430. t30_set_phase_e_handler(t30state, phase_e_handler, s);
  431. start = state_change = ast_tvnow();
  432. ast_activate_generator(s->chan, &generator, &fax);
  433. while (!s->finished) {
  434. inf = NULL;
  435. if ((res = ast_waitfor(s->chan, 25)) < 0) {
  436. ast_debug(1, "Error waiting for a frame\n");
  437. break;
  438. }
  439. /* Watchdog */
  440. now = ast_tvnow();
  441. if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
  442. ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
  443. res = -1;
  444. break;
  445. }
  446. if (!res) {
  447. /* There was timeout waiting for a frame. Loop around and wait again */
  448. continue;
  449. }
  450. /* There is a frame available. Get it */
  451. res = 0;
  452. if (!(inf = ast_read(s->chan))) {
  453. ast_debug(1, "Channel hangup\n");
  454. res = -1;
  455. break;
  456. }
  457. ast_debug(10, "frame %d/%u, len=%d\n", inf->frametype, (unsigned int) inf->subclass.format.id, inf->datalen);
  458. /* Check the frame type. Format also must be checked because there is a chance
  459. that a frame in old format was already queued before we set channel format
  460. to slinear so it will still be received by ast_read */
  461. if (inf->frametype == AST_FRAME_VOICE && inf->subclass.format.id == AST_FORMAT_SLINEAR) {
  462. if (fax_rx(&fax, inf->data.ptr, inf->samples) < 0) {
  463. /* I know fax_rx never returns errors. The check here is for good style only */
  464. ast_log(LOG_WARNING, "fax_rx returned error\n");
  465. res = -1;
  466. break;
  467. }
  468. if (last_state != t30state->state) {
  469. state_change = ast_tvnow();
  470. last_state = t30state->state;
  471. }
  472. } else if ((inf->frametype == AST_FRAME_CONTROL) &&
  473. (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS)) {
  474. struct ast_control_t38_parameters *parameters = inf->data.ptr;
  475. if (parameters->request_response == AST_T38_NEGOTIATED) {
  476. /* T38 switchover completed */
  477. s->t38parameters = *parameters;
  478. ast_debug(1, "T38 negotiated, finishing audio loop\n");
  479. res = 1;
  480. break;
  481. } else if (parameters->request_response == AST_T38_REQUEST_NEGOTIATE) {
  482. t38_parameters.request_response = AST_T38_NEGOTIATED;
  483. ast_debug(1, "T38 request received, accepting\n");
  484. /* Complete T38 switchover */
  485. ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters));
  486. /* Do not break audio loop, wait until channel driver finally acks switchover
  487. * with AST_T38_NEGOTIATED
  488. */
  489. }
  490. }
  491. ast_frfree(inf);
  492. inf = NULL;
  493. }
  494. ast_debug(1, "Loop finished, res=%d\n", res);
  495. if (inf)
  496. ast_frfree(inf);
  497. ast_deactivate_generator(s->chan);
  498. /* If we are switching to T38, remove phase E handler. Otherwise it will be executed
  499. by t30_terminate, display diagnostics and set status variables although no transmittion
  500. has taken place yet. */
  501. if (res > 0) {
  502. t30_set_phase_e_handler(t30state, NULL, NULL);
  503. }
  504. t30_terminate(t30state);
  505. fax_release(&fax);
  506. done:
  507. if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
  508. if (ast_set_write_format(s->chan, &original_write_fmt) < 0)
  509. ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", ast_channel_name(s->chan));
  510. }
  511. if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
  512. if (ast_set_read_format(s->chan, &original_read_fmt) < 0)
  513. ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(s->chan));
  514. }
  515. return res;
  516. }
  517. static int transmit_t38(fax_session *s)
  518. {
  519. int res = 0;
  520. t38_terminal_state_t t38;
  521. struct ast_frame *inf = NULL;
  522. int last_state = 0;
  523. struct timeval now, start, state_change, last_frame;
  524. t30_state_t *t30state;
  525. t38_core_state_t *t38state;
  526. #if SPANDSP_RELEASE_DATE >= 20080725
  527. /* for spandsp shaphots 0.0.6 and higher */
  528. t30state = &t38.t30;
  529. t38state = &t38.t38_fe.t38;
  530. #else
  531. /* for spandsp releases 0.0.5 */
  532. t30state = &t38.t30_state;
  533. t38state = &t38.t38;
  534. #endif
  535. /* Initialize terminal */
  536. memset(&t38, 0, sizeof(t38));
  537. if (t38_terminal_init(&t38, s->caller_mode, t38_tx_packet_handler, s->chan) == NULL) {
  538. ast_log(LOG_WARNING, "Unable to start T.38 termination.\n");
  539. res = -1;
  540. goto disable_t38;
  541. }
  542. t38_set_max_datagram_size(t38state, s->t38parameters.max_ifp);
  543. if (s->t38parameters.fill_bit_removal) {
  544. t38_set_fill_bit_removal(t38state, TRUE);
  545. }
  546. if (s->t38parameters.transcoding_mmr) {
  547. t38_set_mmr_transcoding(t38state, TRUE);
  548. }
  549. if (s->t38parameters.transcoding_jbig) {
  550. t38_set_jbig_transcoding(t38state, TRUE);
  551. }
  552. /* Setup logging */
  553. set_logging(&t38.logging);
  554. set_logging(&t30state->logging);
  555. set_logging(&t38state->logging);
  556. /* Configure terminal */
  557. set_local_info(t30state, s);
  558. set_file(t30state, s);
  559. set_ecm(t30state, TRUE);
  560. t30_set_phase_e_handler(t30state, phase_e_handler, s);
  561. now = start = state_change = ast_tvnow();
  562. while (!s->finished) {
  563. inf = NULL;
  564. if ((res = ast_waitfor(s->chan, 25)) < 0) {
  565. ast_debug(1, "Error waiting for a frame\n");
  566. break;
  567. }
  568. last_frame = now;
  569. /* Watchdog */
  570. now = ast_tvnow();
  571. if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
  572. ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
  573. res = -1;
  574. break;
  575. }
  576. t38_terminal_send_timeout(&t38, ast_tvdiff_us(now, last_frame) / (1000000 / 8000));
  577. if (!res) {
  578. /* There was timeout waiting for a frame. Loop around and wait again */
  579. continue;
  580. }
  581. /* There is a frame available. Get it */
  582. res = 0;
  583. if (!(inf = ast_read(s->chan))) {
  584. ast_debug(1, "Channel hangup\n");
  585. res = -1;
  586. break;
  587. }
  588. ast_debug(10, "frame %d/%d, len=%d\n", inf->frametype, inf->subclass.integer, inf->datalen);
  589. if (inf->frametype == AST_FRAME_MODEM && inf->subclass.integer == AST_MODEM_T38) {
  590. t38_core_rx_ifp_packet(t38state, inf->data.ptr, inf->datalen, inf->seqno);
  591. if (last_state != t30state->state) {
  592. state_change = ast_tvnow();
  593. last_state = t30state->state;
  594. }
  595. } else if (inf->frametype == AST_FRAME_CONTROL && inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) {
  596. struct ast_control_t38_parameters *parameters = inf->data.ptr;
  597. if (parameters->request_response == AST_T38_TERMINATED) {
  598. ast_debug(1, "T38 down, finishing\n");
  599. break;
  600. }
  601. }
  602. ast_frfree(inf);
  603. inf = NULL;
  604. }
  605. ast_debug(1, "Loop finished, res=%d\n", res);
  606. if (inf)
  607. ast_frfree(inf);
  608. t30_terminate(t30state);
  609. t38_terminal_release(&t38);
  610. disable_t38:
  611. /* if we are not the caller, it's our job to shut down the T.38
  612. * session when the FAX transmisson is complete.
  613. */
  614. if ((s->caller_mode == FALSE) &&
  615. (ast_channel_get_t38_state(s->chan) == T38_STATE_NEGOTIATED)) {
  616. struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
  617. if (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0) {
  618. /* wait up to five seconds for negotiation to complete */
  619. unsigned int timeout = 5000;
  620. int ms;
  621. ast_debug(1, "Shutting down T.38 on %s\n", ast_channel_name(s->chan));
  622. while (timeout > 0) {
  623. ms = ast_waitfor(s->chan, 1000);
  624. if (ms < 0) {
  625. ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", ast_channel_name(s->chan));
  626. return -1;
  627. }
  628. if (!ms) {
  629. /* nothing happened */
  630. if (timeout > 0) {
  631. timeout -= 1000;
  632. continue;
  633. } else {
  634. ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 shutdown.\n", ast_channel_name(s->chan));
  635. break;
  636. }
  637. }
  638. if (!(inf = ast_read(s->chan))) {
  639. return -1;
  640. }
  641. if ((inf->frametype == AST_FRAME_CONTROL) &&
  642. (inf->subclass.integer == AST_CONTROL_T38_PARAMETERS) &&
  643. (inf->datalen == sizeof(t38_parameters))) {
  644. struct ast_control_t38_parameters *parameters = inf->data.ptr;
  645. switch (parameters->request_response) {
  646. case AST_T38_TERMINATED:
  647. ast_debug(1, "Shut down T.38 on %s\n", ast_channel_name(s->chan));
  648. break;
  649. case AST_T38_REFUSED:
  650. ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", ast_channel_name(s->chan));
  651. break;
  652. default:
  653. ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", ast_channel_name(s->chan));
  654. break;
  655. }
  656. ast_frfree(inf);
  657. break;
  658. }
  659. ast_frfree(inf);
  660. }
  661. }
  662. }
  663. return res;
  664. }
  665. static int transmit(fax_session *s)
  666. {
  667. int res = 0;
  668. /* Clear all channel variables which to be set by the application.
  669. Pre-set status to error so in case of any problems we can just leave */
  670. pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "FAILED");
  671. pbx_builtin_setvar_helper(s->chan, "FAXERROR", "Channel problems");
  672. pbx_builtin_setvar_helper(s->chan, "FAXMODE", NULL);
  673. pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", NULL);
  674. pbx_builtin_setvar_helper(s->chan, "FAXPAGES", "0");
  675. pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", NULL);
  676. pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", NULL);
  677. if (ast_channel_state(s->chan) != AST_STATE_UP) {
  678. /* Shouldn't need this, but checking to see if channel is already answered
  679. * Theoretically asterisk should already have answered before running the app */
  680. res = ast_answer(s->chan);
  681. if (res) {
  682. ast_log(LOG_WARNING, "Could not answer channel '%s'\n", ast_channel_name(s->chan));
  683. return res;
  684. }
  685. }
  686. s->t38state = ast_channel_get_t38_state(s->chan);
  687. if (s->t38state != T38_STATE_NEGOTIATED) {
  688. /* T38 is not negotiated on the channel yet. First start regular transmission. If it switches to T38, follow */
  689. pbx_builtin_setvar_helper(s->chan, "FAXMODE", "audio");
  690. res = transmit_audio(s);
  691. if (res > 0) {
  692. /* transmit_audio reports switchover to T38. Update t38state */
  693. s->t38state = ast_channel_get_t38_state(s->chan);
  694. if (s->t38state != T38_STATE_NEGOTIATED) {
  695. ast_log(LOG_ERROR, "Audio loop reports T38 switchover but t38state != T38_STATE_NEGOTIATED\n");
  696. }
  697. }
  698. }
  699. if (s->t38state == T38_STATE_NEGOTIATED) {
  700. pbx_builtin_setvar_helper(s->chan, "FAXMODE", "T38");
  701. res = transmit_t38(s);
  702. }
  703. if (res) {
  704. ast_log(LOG_WARNING, "Transmission error\n");
  705. res = -1;
  706. } else if (s->finished < 0) {
  707. ast_log(LOG_WARNING, "Transmission failed\n");
  708. } else if (s->finished > 0) {
  709. ast_debug(1, "Transmission finished Ok\n");
  710. }
  711. return res;
  712. }
  713. /* === Application functions === */
  714. static int sndfax_exec(struct ast_channel *chan, const char *data)
  715. {
  716. int res = 0;
  717. char *parse;
  718. fax_session session = { 0, };
  719. char restore_digit_detect = 0;
  720. AST_DECLARE_APP_ARGS(args,
  721. AST_APP_ARG(file_name);
  722. AST_APP_ARG(options);
  723. );
  724. if (chan == NULL) {
  725. ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
  726. return -1;
  727. }
  728. /* The next few lines of code parse out the filename and header from the input string */
  729. if (ast_strlen_zero(data)) {
  730. /* No data implies no filename or anything is present */
  731. ast_log(LOG_ERROR, "SendFAX requires an argument (filename)\n");
  732. return -1;
  733. }
  734. parse = ast_strdupa(data);
  735. AST_STANDARD_APP_ARGS(args, parse);
  736. session.caller_mode = TRUE;
  737. if (args.options) {
  738. if (strchr(args.options, 'a'))
  739. session.caller_mode = FALSE;
  740. }
  741. /* Done parsing */
  742. session.direction = 1;
  743. session.file_name = args.file_name;
  744. session.chan = chan;
  745. session.finished = 0;
  746. /* get current digit detection mode, then disable digit detection if enabled */
  747. {
  748. int dummy = sizeof(restore_digit_detect);
  749. ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, &dummy, 0);
  750. }
  751. if (restore_digit_detect) {
  752. char new_digit_detect = 0;
  753. ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &new_digit_detect, sizeof(new_digit_detect), 0);
  754. }
  755. /* disable FAX tone detection if enabled */
  756. {
  757. char new_fax_detect = 0;
  758. ast_channel_setoption(chan, AST_OPTION_FAX_DETECT, &new_fax_detect, sizeof(new_fax_detect), 0);
  759. }
  760. res = transmit(&session);
  761. if (restore_digit_detect) {
  762. ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, sizeof(restore_digit_detect), 0);
  763. }
  764. return res;
  765. }
  766. static int rcvfax_exec(struct ast_channel *chan, const char *data)
  767. {
  768. int res = 0;
  769. char *parse;
  770. fax_session session;
  771. char restore_digit_detect = 0;
  772. AST_DECLARE_APP_ARGS(args,
  773. AST_APP_ARG(file_name);
  774. AST_APP_ARG(options);
  775. );
  776. if (chan == NULL) {
  777. ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
  778. return -1;
  779. }
  780. /* The next few lines of code parse out the filename and header from the input string */
  781. if (ast_strlen_zero(data)) {
  782. /* No data implies no filename or anything is present */
  783. ast_log(LOG_ERROR, "ReceiveFAX requires an argument (filename)\n");
  784. return -1;
  785. }
  786. parse = ast_strdupa(data);
  787. AST_STANDARD_APP_ARGS(args, parse);
  788. session.caller_mode = FALSE;
  789. if (args.options) {
  790. if (strchr(args.options, 'c'))
  791. session.caller_mode = TRUE;
  792. }
  793. /* Done parsing */
  794. session.direction = 0;
  795. session.file_name = args.file_name;
  796. session.chan = chan;
  797. session.finished = 0;
  798. /* get current digit detection mode, then disable digit detection if enabled */
  799. {
  800. int dummy = sizeof(restore_digit_detect);
  801. ast_channel_queryoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, &dummy, 0);
  802. }
  803. if (restore_digit_detect) {
  804. char new_digit_detect = 0;
  805. ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &new_digit_detect, sizeof(new_digit_detect), 0);
  806. }
  807. /* disable FAX tone detection if enabled */
  808. {
  809. char new_fax_detect = 0;
  810. ast_channel_setoption(chan, AST_OPTION_FAX_DETECT, &new_fax_detect, sizeof(new_fax_detect), 0);
  811. }
  812. res = transmit(&session);
  813. if (restore_digit_detect) {
  814. ast_channel_setoption(chan, AST_OPTION_DIGIT_DETECT, &restore_digit_detect, sizeof(restore_digit_detect), 0);
  815. }
  816. return res;
  817. }
  818. static int unload_module(void)
  819. {
  820. int res;
  821. res = ast_unregister_application(app_sndfax_name);
  822. res |= ast_unregister_application(app_rcvfax_name);
  823. return res;
  824. }
  825. static int load_module(void)
  826. {
  827. int res ;
  828. res = ast_register_application_xml(app_sndfax_name, sndfax_exec);
  829. res |= ast_register_application_xml(app_rcvfax_name, rcvfax_exec);
  830. /* The default SPAN message handler prints to stderr. It is something we do not want */
  831. span_set_message_handler(NULL);
  832. return res;
  833. }
  834. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Simple FAX Application",
  835. .load = load_module,
  836. .unload = unload_module,
  837. );