81711bb40c2f89d100ecf77cb9d97387a7ec346d
[asterisk/asterisk.git] / res / res_fax_spandsp.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009-2010, Digium, Inc.
5  *
6  * Matthew Nicholson <mnicholson@digium.com>
7  *
8  * Initial T.38-gateway code
9  * 2008, Daniel Ferenci <daniel.ferenci@nethemba.com>
10  * Created by Nethemba s.r.o. http://www.nethemba.com
11  * Sponsored by IPEX a.s. http://www.ipex.cz
12  *
13  * T.38-gateway integration into asterisk app_fax and rework
14  * 2008, Gregory Hinton Nietsky <gregory@dnstelecom.co.za>
15  * dns Telecom http://www.dnstelecom.co.za
16  *
17  * Modified to make T.38-gateway compatible with Asterisk 1.6.2
18  * 2010, Anton Verevkin <mymail@verevkin.it>
19  * ViaNetTV http://www.vianettv.com
20  *
21  * Modified to make T.38-gateway work
22  * 2010, Klaus Darilion, IPCom GmbH, www.ipcom.at
23  *
24  * See http://www.asterisk.org for more information about
25  * the Asterisk project. Please do not directly contact
26  * any of the maintainers of this project for assistance;
27  * the project provides a web site, mailing lists and IRC
28  * channels for your use.
29  *
30  * This program is free software, distributed under the terms of
31  * the GNU General Public License Version 2. See the LICENSE file
32  * at the top of the source tree.
33  */
34
35 /*! \file
36  *
37  * \brief Spandsp T.38 and G.711 FAX Resource
38  *
39  * \author Matthew Nicholson <mnicholson@digium.com>
40  * \author Gregory H. Nietsky <gregory@distrotech.co.za>
41  *
42  * This module registers the Spandsp FAX technology with the res_fax module.
43  */
44
45 /*** MODULEINFO
46         <depend>spandsp</depend>
47         <depend>res_fax</depend>
48         <support_level>extended</support_level>
49 ***/
50
51 #include "asterisk.h"
52
53 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
54
55 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
56 #include <spandsp.h>
57 #include <spandsp/version.h>
58
59 #include "asterisk/logger.h"
60 #include "asterisk/module.h"
61 #include "asterisk/strings.h"
62 #include "asterisk/cli.h"
63 #include "asterisk/utils.h"
64 #include "asterisk/timing.h"
65 #include "asterisk/astobj2.h"
66 #include "asterisk/res_fax.h"
67 #include "asterisk/channel.h"
68
69 #define SPANDSP_FAX_SAMPLES 160
70 #define SPANDSP_FAX_TIMER_RATE 8000 / SPANDSP_FAX_SAMPLES       /* 50 ticks per second, 20ms, 160 samples per second */
71 #define SPANDSP_ENGAGE_UDPTL_NAT_RETRY 3
72
73 static void *spandsp_fax_new(struct ast_fax_session *s, struct ast_fax_tech_token *token);
74 static void spandsp_fax_destroy(struct ast_fax_session *s);
75 static struct ast_frame *spandsp_fax_read(struct ast_fax_session *s);
76 static int spandsp_fax_write(struct ast_fax_session *s, const struct ast_frame *f);
77 static int spandsp_fax_start(struct ast_fax_session *s);
78 static int spandsp_fax_cancel(struct ast_fax_session *s);
79 static int spandsp_fax_switch_to_t38(struct ast_fax_session *s);
80 static int spandsp_fax_gateway_start(struct ast_fax_session *s);
81 static int spandsp_fax_gateway_process(struct ast_fax_session *s, const struct ast_frame *f);
82 static void spandsp_fax_gateway_cleanup(struct ast_fax_session *s);
83
84 static char *spandsp_fax_cli_show_capabilities(int fd);
85 static char *spandsp_fax_cli_show_session(struct ast_fax_session *s, int fd);
86 static char *spandsp_fax_cli_show_stats(int fd);
87 static char *spandsp_fax_cli_show_settings(int fd);
88
89 static struct ast_fax_tech spandsp_fax_tech = {
90         .type = "Spandsp",
91         .description = "Spandsp FAX Driver",
92 #if SPANDSP_RELEASE_DATE >= 20090220
93         /* spandsp 0.0.6 */
94         .version = SPANDSP_RELEASE_DATETIME_STRING,
95 #else
96         /* spandsp 0.0.5
97          * TODO: maybe we should determine the version better way
98          */
99         .version = "pre-20090220",
100 #endif
101         .caps = AST_FAX_TECH_AUDIO | AST_FAX_TECH_T38 | AST_FAX_TECH_SEND | AST_FAX_TECH_RECEIVE | AST_FAX_TECH_GATEWAY,
102         .new_session = spandsp_fax_new,
103         .destroy_session = spandsp_fax_destroy,
104         .read = spandsp_fax_read,
105         .write = spandsp_fax_write,
106         .start_session = spandsp_fax_start,
107         .cancel_session = spandsp_fax_cancel,
108         .switch_to_t38 = spandsp_fax_switch_to_t38,
109         .cli_show_capabilities = spandsp_fax_cli_show_capabilities,
110         .cli_show_session = spandsp_fax_cli_show_session,
111         .cli_show_stats = spandsp_fax_cli_show_stats,
112         .cli_show_settings = spandsp_fax_cli_show_settings,
113 };
114
115 struct spandsp_fax_stats {
116         int success;
117         int nofax;
118         int neg_failed;
119         int failed_to_train;
120         int rx_protocol_error;
121         int tx_protocol_error;
122         int protocol_error;
123         int retries_exceeded;
124         int file_error;
125         int mem_error;
126         int call_dropped;
127         int unknown_error;
128         int switched;
129 };
130
131 static struct {
132         ast_mutex_t lock;
133         struct spandsp_fax_stats g711;
134         struct spandsp_fax_stats t38;
135 } spandsp_global_stats;
136
137 struct spandsp_pvt {
138         unsigned int ist38:1;
139         unsigned int isdone:1;
140         enum ast_t38_state ast_t38_state;
141         fax_state_t fax_state;
142         t38_terminal_state_t t38_state;
143         t30_state_t *t30_state;
144         t38_core_state_t *t38_core_state;
145
146         struct spandsp_fax_stats *stats;
147
148         struct spandsp_fax_gw_stats *t38stats;
149         t38_gateway_state_t t38_gw_state;
150
151         struct ast_timer *timer;
152         AST_LIST_HEAD(frame_queue, ast_frame) read_frames;
153 };
154
155 static void session_destroy(struct spandsp_pvt *p);
156 static int t38_tx_packet_handler(t38_core_state_t *t38_core_state, void *data, const uint8_t *buf, int len, int count);
157 static void t30_phase_e_handler(t30_state_t *t30_state, void *data, int completion_code);
158 static void spandsp_log(int level, const char *msg);
159 static int update_stats(struct spandsp_pvt *p, int completion_code);
160
161 static void set_logging(logging_state_t *state, struct ast_fax_session_details *details);
162 static void set_local_info(t30_state_t *t30_state, struct ast_fax_session_details *details);
163 static void set_file(t30_state_t *t30_state, struct ast_fax_session_details *details);
164 static void set_ecm(t30_state_t *t30_state, struct ast_fax_session_details *details);
165
166 static void session_destroy(struct spandsp_pvt *p)
167 {
168         struct ast_frame *f;
169
170         t30_terminate(p->t30_state);
171         p->isdone = 1;
172
173         ast_timer_close(p->timer);
174
175         fax_release(&p->fax_state);
176         t38_terminal_release(&p->t38_state);
177
178         while ((f = AST_LIST_REMOVE_HEAD(&p->read_frames, frame_list))) {
179                 ast_frfree(f);
180         }
181 }
182
183 /*! \brief
184  *
185  */
186 static int t38_tx_packet_handler(t38_core_state_t *t38_core_state, void *data, const uint8_t *buf, int len, int count)
187 {
188         int res = -1;
189         struct ast_fax_session *s = data;
190         struct spandsp_pvt *p = s->tech_pvt;
191         struct ast_frame fax_frame = {
192                 .frametype = AST_FRAME_MODEM,
193                 .subclass.integer = AST_MODEM_T38,
194                 .src = "res_fax_spandsp_t38",
195         };
196
197         struct ast_frame *f = &fax_frame;
198
199
200         /* TODO: Asterisk does not provide means of resending the same packet multiple
201           times so count is ignored at the moment */
202
203         AST_FRAME_SET_BUFFER(f, buf, 0, len);
204
205         if (!(f = ast_frisolate(f))) {
206                 return res;
207         }
208
209         if (s->details->caps & AST_FAX_TECH_GATEWAY) {
210                 ast_set_flag(f, AST_FAX_FRFLAG_GATEWAY);
211                 if (p->ast_t38_state == T38_STATE_NEGOTIATED) {
212                         res = ast_write(s->chan, f);
213                 } else {
214                         res = ast_queue_frame(s->chan, f);
215                 }
216                 ast_frfree(f);
217         } else {
218                 /* no need to lock, this all runs in the same thread */
219                 AST_LIST_INSERT_TAIL(&p->read_frames, f, frame_list);
220         }
221
222         return res;
223 }
224
225 static int update_stats(struct spandsp_pvt *p, int completion_code)
226 {
227         switch (completion_code) {
228         case T30_ERR_OK:
229                 ast_atomic_fetchadd_int(&p->stats->success, 1);
230                 break;
231
232         /* Link problems */
233         case T30_ERR_CEDTONE:            /*! The CED tone exceeded 5s */
234         case T30_ERR_T0_EXPIRED:         /*! Timed out waiting for initial communication */
235         case T30_ERR_T1_EXPIRED:         /*! Timed out waiting for the first message */
236         case T30_ERR_T3_EXPIRED:         /*! Timed out waiting for procedural interrupt */
237         case T30_ERR_HDLC_CARRIER:       /*! The HDLC carrier did not stop in a timely manner */
238         case T30_ERR_CANNOT_TRAIN:       /*! Failed to train with any of the compatible modems */
239                 ast_atomic_fetchadd_int(&p->stats->failed_to_train, 1);
240                 break;
241
242         case T30_ERR_OPER_INT_FAIL:      /*! Operator intervention failed */
243         case T30_ERR_INCOMPATIBLE:       /*! Far end is not compatible */
244         case T30_ERR_RX_INCAPABLE:       /*! Far end is not able to receive */
245         case T30_ERR_TX_INCAPABLE:       /*! Far end is not able to transmit */
246         case T30_ERR_NORESSUPPORT:       /*! Far end cannot receive at the resolution of the image */
247         case T30_ERR_NOSIZESUPPORT:      /*! Far end cannot receive at the size of image */
248                 ast_atomic_fetchadd_int(&p->stats->neg_failed, 1);
249                 break;
250
251         case T30_ERR_UNEXPECTED:         /*! Unexpected message received */
252                 ast_atomic_fetchadd_int(&p->stats->protocol_error, 1);
253                 break;
254
255         /* Phase E status values returned to a transmitter */
256         case T30_ERR_TX_BADDCS:          /*! Received bad response to DCS or training */
257         case T30_ERR_TX_BADPG:           /*! Received a DCN from remote after sending a page */
258         case T30_ERR_TX_ECMPHD:          /*! Invalid ECM response received from receiver */
259         case T30_ERR_TX_GOTDCN:          /*! Received a DCN while waiting for a DIS */
260         case T30_ERR_TX_INVALRSP:        /*! Invalid response after sending a page */
261         case T30_ERR_TX_NODIS:           /*! Received other than DIS while waiting for DIS */
262         case T30_ERR_TX_PHBDEAD:         /*! Received no response to DCS, training or TCF */
263         case T30_ERR_TX_PHDDEAD:         /*! No response after sending a page */
264         case T30_ERR_TX_T5EXP:           /*! Timed out waiting for receiver ready (ECM mode) */
265                 ast_atomic_fetchadd_int(&p->stats->tx_protocol_error, 1);
266                 break;
267
268         /* Phase E status values returned to a receiver */
269         case T30_ERR_RX_ECMPHD:          /*! Invalid ECM response received from transmitter */
270         case T30_ERR_RX_GOTDCS:          /*! DCS received while waiting for DTC */
271         case T30_ERR_RX_INVALCMD:        /*! Unexpected command after page received */
272         case T30_ERR_RX_NOCARRIER:       /*! Carrier lost during fax receive */
273         case T30_ERR_RX_NOEOL:           /*! Timed out while waiting for EOL (end Of line) */
274                 ast_atomic_fetchadd_int(&p->stats->rx_protocol_error, 1);
275                 break;
276         case T30_ERR_RX_NOFAX:           /*! Timed out while waiting for first line */
277                 ast_atomic_fetchadd_int(&p->stats->nofax, 1);
278                 break;
279         case T30_ERR_RX_T2EXPDCN:        /*! Timer T2 expired while waiting for DCN */
280         case T30_ERR_RX_T2EXPD:          /*! Timer T2 expired while waiting for phase D */
281         case T30_ERR_RX_T2EXPFAX:        /*! Timer T2 expired while waiting for fax page */
282         case T30_ERR_RX_T2EXPMPS:        /*! Timer T2 expired while waiting for next fax page */
283         case T30_ERR_RX_T2EXPRR:         /*! Timer T2 expired while waiting for RR command */
284         case T30_ERR_RX_T2EXP:           /*! Timer T2 expired while waiting for NSS, DCS or MCF */
285         case T30_ERR_RX_DCNWHY:          /*! Unexpected DCN while waiting for DCS or DIS */
286         case T30_ERR_RX_DCNDATA:         /*! Unexpected DCN while waiting for image data */
287         case T30_ERR_RX_DCNFAX:          /*! Unexpected DCN while waiting for EOM, EOP or MPS */
288         case T30_ERR_RX_DCNPHD:          /*! Unexpected DCN after EOM or MPS sequence */
289         case T30_ERR_RX_DCNRRD:          /*! Unexpected DCN after RR/RNR sequence */
290         case T30_ERR_RX_DCNNORTN:        /*! Unexpected DCN after requested retransmission */
291                 ast_atomic_fetchadd_int(&p->stats->rx_protocol_error, 1);
292                 break;
293
294         /* TIFF file problems */
295         case T30_ERR_FILEERROR:          /*! TIFF/F file cannot be opened */
296         case T30_ERR_NOPAGE:             /*! TIFF/F page not found */
297         case T30_ERR_BADTIFF:            /*! TIFF/F format is not compatible */
298         case T30_ERR_BADPAGE:            /*! TIFF/F page number tag missing */
299         case T30_ERR_BADTAG:             /*! Incorrect values for TIFF/F tags */
300         case T30_ERR_BADTIFFHDR:         /*! Bad TIFF/F header - incorrect values in fields */
301                 ast_atomic_fetchadd_int(&p->stats->file_error, 1);
302                 break;
303         case T30_ERR_NOMEM:              /*! Cannot allocate memory for more pages */
304                 ast_atomic_fetchadd_int(&p->stats->mem_error, 1);
305                 break;
306
307         /* General problems */
308         case T30_ERR_RETRYDCN:           /*! Disconnected after permitted retries */
309                 ast_atomic_fetchadd_int(&p->stats->retries_exceeded, 1);
310                 break;
311         case T30_ERR_CALLDROPPED:        /*! The call dropped prematurely */
312                 ast_atomic_fetchadd_int(&p->stats->call_dropped, 1);
313                 break;
314
315         /* Feature negotiation issues */
316         case T30_ERR_NOPOLL:             /*! Poll not accepted */
317         case T30_ERR_IDENT_UNACCEPTABLE: /*! Far end's ident is not acceptable */
318         case T30_ERR_SUB_UNACCEPTABLE:   /*! Far end's sub-address is not acceptable */
319         case T30_ERR_SEP_UNACCEPTABLE:   /*! Far end's selective polling address is not acceptable */
320         case T30_ERR_PSA_UNACCEPTABLE:   /*! Far end's polled sub-address is not acceptable */
321         case T30_ERR_SID_UNACCEPTABLE:   /*! Far end's sender identification is not acceptable */
322         case T30_ERR_PWD_UNACCEPTABLE:   /*! Far end's password is not acceptable */
323         case T30_ERR_TSA_UNACCEPTABLE:   /*! Far end's transmitting subscriber internet address is not acceptable */
324         case T30_ERR_IRA_UNACCEPTABLE:   /*! Far end's internet routing address is not acceptable */
325         case T30_ERR_CIA_UNACCEPTABLE:   /*! Far end's calling subscriber internet address is not acceptable */
326         case T30_ERR_ISP_UNACCEPTABLE:   /*! Far end's internet selective polling address is not acceptable */
327         case T30_ERR_CSA_UNACCEPTABLE:   /*! Far end's called subscriber internet address is not acceptable */
328                 ast_atomic_fetchadd_int(&p->stats->neg_failed, 1);
329                 break;
330         default:
331                 ast_atomic_fetchadd_int(&p->stats->unknown_error, 1);
332                 ast_log(LOG_WARNING, "unknown FAX session result '%d' (%s)\n", completion_code, t30_completion_code_to_str(completion_code));
333                 return -1;
334         }
335         return 0;
336 }
337
338 /*! \brief Phase E handler callback.
339  * \param t30_state the span t30 state
340  * \param data this will be the ast_fax_session
341  * \param completion_code the result of the fax session
342  *
343  * This function pulls stats from the spandsp stack and stores them for res_fax
344  * to use later.
345  */
346 static void t30_phase_e_handler(t30_state_t *t30_state, void *data, int completion_code)
347 {
348         struct ast_fax_session *s = data;
349         struct spandsp_pvt *p = s->tech_pvt;
350         char headerinfo[T30_MAX_PAGE_HEADER_INFO + 1];
351         const char *c;
352         t30_stats_t stats;
353
354         ast_debug(5, "FAX session '%d' entering phase E\n", s->id);
355
356         p->isdone = 1;
357
358         update_stats(p, completion_code);
359
360         t30_get_transfer_statistics(t30_state, &stats);
361
362         if (completion_code == T30_ERR_OK) {
363                 ast_string_field_set(s->details, result, "SUCCESS");
364         } else {
365                 ast_string_field_set(s->details, result, "FAILED");
366                 ast_string_field_set(s->details, error, t30_completion_code_to_str(completion_code));
367         }
368
369         ast_string_field_set(s->details, resultstr, t30_completion_code_to_str(completion_code));
370
371         ast_debug(5, "FAX session '%d' completed with result: %s (%s)\n", s->id, s->details->result, s->details->resultstr);
372
373         if ((c = t30_get_tx_ident(t30_state))) {
374                 ast_string_field_set(s->details, localstationid, c);
375         }
376
377         if ((c = t30_get_rx_ident(t30_state))) {
378                 ast_string_field_set(s->details, remotestationid, c);
379         }
380
381 #if SPANDSP_RELEASE_DATE >= 20090220
382         s->details->pages_transferred = (s->details->caps & AST_FAX_TECH_RECEIVE) ? stats.pages_rx : stats.pages_tx;
383 #else
384         s->details->pages_transferred = stats.pages_transferred;
385 #endif
386
387         ast_string_field_build(s->details, transfer_rate, "%d", stats.bit_rate);
388
389         ast_string_field_build(s->details, resolution, "%dx%d", stats.x_resolution, stats.y_resolution);
390
391         t30_get_tx_page_header_info(t30_state, headerinfo);
392         ast_string_field_set(s->details, headerinfo, headerinfo);
393 }
394
395 /*! \brief Send spandsp log messages to asterisk.
396  * \param level the spandsp logging level
397  * \param msg the log message
398  *
399  * \note This function is a callback function called by spandsp.
400  */
401 static void spandsp_log(int level, const char *msg)
402 {
403         if (level == SPAN_LOG_ERROR) {
404                 ast_log(LOG_ERROR, "%s", msg);
405         } else if (level == SPAN_LOG_WARNING) {
406                 ast_log(LOG_WARNING, "%s", msg);
407         } else {
408                 ast_fax_log(LOG_DEBUG, msg);
409         }
410 }
411
412 static void set_logging(logging_state_t *state, struct ast_fax_session_details *details)
413 {
414         int level = SPAN_LOG_WARNING;
415
416         if (details->option.debug) {
417                 level = SPAN_LOG_DEBUG_3;
418         }
419
420         span_log_set_message_handler(state, spandsp_log);
421         span_log_set_level(state, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | level);
422 }
423
424 static void set_local_info(t30_state_t *t30_state, struct ast_fax_session_details *details)
425 {
426         if (!ast_strlen_zero(details->localstationid)) {
427                 t30_set_tx_ident(t30_state, details->localstationid);
428         }
429
430         if (!ast_strlen_zero(details->headerinfo)) {
431                 t30_set_tx_page_header_info(t30_state, details->headerinfo);
432         }
433 }
434
435 static void set_file(t30_state_t *t30_state, struct ast_fax_session_details *details)
436 {
437         if (details->caps & AST_FAX_TECH_RECEIVE) {
438                 t30_set_rx_file(t30_state, AST_LIST_FIRST(&details->documents)->filename, -1);
439         } else {
440                 /* if not AST_FAX_TECH_RECEIVE, assume AST_FAX_TECH_SEND, this
441                  * should be safe because we ensure either RECEIVE or SEND is
442                  * indicated in spandsp_fax_new() */
443                 t30_set_tx_file(t30_state, AST_LIST_FIRST(&details->documents)->filename, -1, -1);
444         }
445 }
446
447 static void set_ecm(t30_state_t *t30_state, struct ast_fax_session_details *details)
448 {
449         t30_set_ecm_capability(t30_state, details->option.ecm);
450         t30_set_supported_compressions(t30_state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
451 }
452
453 /*! \brief create an instance of the spandsp tech_pvt for a fax session */
454 static void *spandsp_fax_new(struct ast_fax_session *s, struct ast_fax_tech_token *token)
455 {
456         struct spandsp_pvt *p;
457         int caller_mode;
458
459         if ((!(p = ast_calloc(1, sizeof(*p))))) {
460                 ast_log(LOG_ERROR, "Cannot initialize the spandsp private FAX technology structure.\n");
461                 goto e_return;
462         }
463
464         if (s->details->caps & AST_FAX_TECH_GATEWAY) {
465                 s->state = AST_FAX_STATE_INITIALIZED;
466                 return p;
467         }
468
469         AST_LIST_HEAD_INIT(&p->read_frames);
470
471         if (s->details->caps & AST_FAX_TECH_RECEIVE) {
472                 caller_mode = 0;
473         } else if (s->details->caps & AST_FAX_TECH_SEND) {
474                 caller_mode = 1;
475         } else {
476                 ast_log(LOG_ERROR, "Are we sending or receiving? The FAX requirements (capabilities: 0x%X) were not properly set.\n", s->details->caps);
477                 goto e_free;
478         }
479
480         if (!(p->timer = ast_timer_open())) {
481                 ast_log(LOG_ERROR, "Channel '%s' FAX session '%d' failed to create timing source.\n", s->channame, s->id);
482                 goto e_free;
483         }
484
485         s->fd = ast_timer_fd(p->timer);
486
487         p->stats = &spandsp_global_stats.g711;
488
489         if (s->details->caps & AST_FAX_TECH_T38) {
490                 if ((s->details->caps & AST_FAX_TECH_AUDIO) == 0) {
491                         /* audio mode was not requested, start in T.38 mode */
492                         p->ist38 = 1;
493                         p->stats = &spandsp_global_stats.t38;
494                 }
495
496                 /* init t38 stuff */
497                 t38_terminal_init(&p->t38_state, caller_mode, t38_tx_packet_handler, s);
498                 set_logging(&p->t38_state.logging, s->details);
499         }
500
501         if (s->details->caps & AST_FAX_TECH_AUDIO) {
502                 /* init audio stuff */
503                 fax_init(&p->fax_state, caller_mode);
504                 set_logging(&p->fax_state.logging, s->details);
505         }
506
507         s->state = AST_FAX_STATE_INITIALIZED;
508         return p;
509
510 e_free:
511         ast_free(p);
512 e_return:
513         return NULL;
514 }
515
516 /*! \brief Destroy a spandsp fax session.
517  */
518 static void spandsp_fax_destroy(struct ast_fax_session *s)
519 {
520         struct spandsp_pvt *p = s->tech_pvt;
521
522         if (s->details->caps & AST_FAX_TECH_GATEWAY) {
523                 spandsp_fax_gateway_cleanup(s);
524         } else {
525                 session_destroy(p);
526         }
527
528         ast_free(p);
529         s->tech_pvt = NULL;
530         s->fd = -1;
531 }
532
533 /*! \brief Read a frame from the spandsp fax stack.
534  */
535 static struct ast_frame *spandsp_fax_read(struct ast_fax_session *s)
536 {
537         struct spandsp_pvt *p = s->tech_pvt;
538         uint8_t buffer[AST_FRIENDLY_OFFSET + SPANDSP_FAX_SAMPLES * sizeof(uint16_t)];
539         int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
540         int samples;
541
542         struct ast_frame fax_frame = {
543                 .frametype = AST_FRAME_VOICE,
544                 .src = "res_fax_spandsp_g711",
545         };
546         struct ast_frame *f = &fax_frame;
547         ast_format_set(&fax_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
548
549         ast_timer_ack(p->timer, 1);
550
551         /* XXX do we need to lock here? */
552         if (p->isdone) {
553                 s->state = AST_FAX_STATE_COMPLETE;
554                 ast_debug(5, "FAX session '%d' is complete.\n", s->id);
555                 return NULL;
556         }
557
558         if (p->ist38) {
559                 t38_terminal_send_timeout(&p->t38_state, SPANDSP_FAX_SAMPLES);
560                 if ((f = AST_LIST_REMOVE_HEAD(&p->read_frames, frame_list))) {
561                         return f;
562                 }
563         } else {
564                 if ((samples = fax_tx(&p->fax_state, buf, SPANDSP_FAX_SAMPLES)) > 0) {
565                         f->samples = samples;
566                         AST_FRAME_SET_BUFFER(f, buffer, AST_FRIENDLY_OFFSET, samples * sizeof(int16_t));
567                         return ast_frisolate(f);
568                 }
569         }
570
571         return &ast_null_frame;
572 }
573
574 /*! \brief Write a frame to the spandsp fax stack.
575  * \param s a fax session
576  * \param f the frame to write
577  *
578  * \note res_fax does not currently use the return value of this function.
579  * Also the fax_rx() function never fails.
580  *
581  * \retval 0 success
582  * \retval -1 failure
583  */
584 static int spandsp_fax_write(struct ast_fax_session *s, const struct ast_frame *f)
585 {
586         struct spandsp_pvt *p = s->tech_pvt;
587
588         if (s->details->caps & AST_FAX_TECH_GATEWAY) {
589                 return spandsp_fax_gateway_process(s, f);
590         }
591
592         /* XXX do we need to lock here? */
593         if (s->state == AST_FAX_STATE_COMPLETE) {
594                 ast_log(LOG_WARNING, "FAX session '%d' is in the '%s' state.\n", s->id, ast_fax_state_to_str(s->state));
595                 return -1;
596         }
597
598         if (p->ist38) {
599                 return t38_core_rx_ifp_packet(p->t38_core_state, f->data.ptr, f->datalen, f->seqno);
600         } else {
601                 return fax_rx(&p->fax_state, f->data.ptr, f->samples);
602         }
603 }
604
605 /*! \brief generate T.30 packets sent to the T.30 leg of gateway
606  * \param chan T.30 channel
607  * \param data fax session structure
608  * \param len not used
609  * \param samples no of samples generated
610  * \return -1 on failure or 0 on sucess*/
611 static int spandsp_fax_gw_t30_gen(struct ast_channel *chan, void *data, int len, int samples)
612 {
613         int res = -1;
614         struct ast_fax_session *s = data;
615         struct spandsp_pvt *p = s->tech_pvt;
616         uint8_t buffer[AST_FRIENDLY_OFFSET + samples * sizeof(uint16_t)];
617         struct ast_frame *f;
618         struct ast_frame t30_frame = {
619                 .frametype = AST_FRAME_VOICE,
620                 .src = "res_fax_spandsp_g711",
621                 .samples = samples,
622                 .flags = AST_FAX_FRFLAG_GATEWAY,
623         };
624
625         AST_FRAME_SET_BUFFER(&t30_frame, buffer, AST_FRIENDLY_OFFSET, t30_frame.samples * sizeof(int16_t));
626
627         ast_format_set(&t30_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
628         if (!(f = ast_frisolate(&t30_frame))) {
629                 return p->isdone ? -1 : res;
630         }
631
632         /* generate a T.30 packet */
633         if ((f->samples = t38_gateway_tx(&p->t38_gw_state, f->data.ptr, f->samples))) {
634                 f->datalen = f->samples * sizeof(int16_t);
635                 res = ast_write(chan, f);
636         }
637         ast_frfree(f);
638         return p->isdone ? -1 : res;
639 }
640
641 /*! \brief simple routine to allocate data to generator
642  * \param chan channel
643  * \param params generator data
644  * \return data to use in generator call*/
645 static void *spandsp_fax_gw_gen_alloc(struct ast_channel *chan, void *params) {
646         ao2_ref(params, +1);
647         return params;
648 }
649
650 static void spandsp_fax_gw_gen_release(struct ast_channel *chan, void *data) {
651         ao2_ref(data, -1);
652 }
653
654 /*! \brief activate a spandsp gateway based on the information in the given fax session
655  * \param s fax session
656  * \return -1 on error 0 on sucess*/
657 static int spandsp_fax_gateway_start(struct ast_fax_session *s) {
658         struct spandsp_pvt *p = s->tech_pvt;
659         struct ast_fax_t38_parameters *t38_param;
660         int i, modems = 0;
661         struct ast_channel *peer;
662         static struct ast_generator t30_gen = {
663                 alloc: spandsp_fax_gw_gen_alloc,
664                 release: spandsp_fax_gw_gen_release,
665                 generate: spandsp_fax_gw_t30_gen,
666         };
667
668 #if SPANDSP_RELEASE_DATE >= 20081012
669         /* for spandsp shaphots 0.0.6 and higher */
670         p->t38_core_state=&p->t38_gw_state.t38x.t38;
671 #else
672         /* for spandsp release 0.0.5 */
673         p->t38_core_state=&p->t38_gw_state.t38;
674 #endif
675
676         if (!t38_gateway_init(&p->t38_gw_state, t38_tx_packet_handler, s)) {
677                 return -1;
678         }
679
680         p->ist38 = 1;
681         p->ast_t38_state = ast_channel_get_t38_state(s->chan);
682         if (!(peer = ast_bridged_channel(s->chan))) {
683                 ast_channel_unlock(s->chan);
684                 return -1;
685         }
686
687         /* we can be in T38_STATE_NEGOTIATING or T38_STATE_NEGOTIATED when the
688          * gateway is started. We treat both states the same. */
689         if (p->ast_t38_state == T38_STATE_NEGOTIATING) {
690                 p->ast_t38_state = T38_STATE_NEGOTIATED;
691         }
692
693         ast_activate_generator(p->ast_t38_state == T38_STATE_NEGOTIATED ? peer : s->chan, &t30_gen , s);
694
695         set_logging(&p->t38_gw_state.logging, s->details);
696         set_logging(&p->t38_core_state->logging, s->details);
697
698         t38_param = (p->ast_t38_state == T38_STATE_NEGOTIATED) ? &s->details->our_t38_parameters : &s->details->their_t38_parameters;
699         t38_set_t38_version(p->t38_core_state, t38_param->version);
700         t38_gateway_set_ecm_capability(&p->t38_gw_state, s->details->option.ecm);
701         t38_set_max_datagram_size(p->t38_core_state, t38_param->max_ifp);
702         t38_set_fill_bit_removal(p->t38_core_state, t38_param->fill_bit_removal);
703         t38_set_mmr_transcoding(p->t38_core_state, t38_param->transcoding_mmr);
704         t38_set_jbig_transcoding(p->t38_core_state, t38_param->transcoding_jbig);
705         t38_set_data_rate_management_method(p->t38_core_state, 
706                         (t38_param->rate_management == AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF)? 1 : 2);
707
708         t38_gateway_set_transmit_on_idle(&p->t38_gw_state, TRUE);
709         t38_set_sequence_number_handling(p->t38_core_state, TRUE);
710
711         if (AST_FAX_MODEM_V17 & s->details->modems) {
712                 modems |= T30_SUPPORT_V17;
713         }
714         if (AST_FAX_MODEM_V27 & s->details->modems) {
715                 modems |= T30_SUPPORT_V27TER;
716         }
717         if (AST_FAX_MODEM_V29 & s->details->modems) {
718                 modems |= T30_SUPPORT_V29;
719         }
720         if (AST_FAX_MODEM_V34 & s->details->modems) {
721 #if defined(T30_SUPPORT_V34)
722                 modems |= T30_SUPPORT_V34;
723 #elif defined(T30_SUPPORT_V34HDX)
724                 modems |= T30_SUPPORT_V34HDX;
725 #else
726                 ast_log(LOG_WARNING, "v34 not supported in this version of spandsp\n");
727 #endif
728         }
729
730         t38_gateway_set_supported_modems(&p->t38_gw_state, modems);
731
732         /* engage udptl nat on other side of T38 line 
733          * (Asterisk changes media ports thus we send a few packets to reinitialize
734          * pinholes in NATs and FWs
735          */
736         for (i=0; i < SPANDSP_ENGAGE_UDPTL_NAT_RETRY; i++) {
737 #if SPANDSP_RELEASE_DATE >= 20091228
738                 t38_core_send_indicator(&p->t38_gw_state.t38x.t38, T38_IND_NO_SIGNAL);
739 #elif SPANDSP_RELEASE_DATE >= 20081012
740                 t38_core_send_indicator(&p->t38_gw_state.t38x.t38, T38_IND_NO_SIGNAL, p->t38_gw_state.t38x.t38.indicator_tx_count);
741 #else
742                 t38_core_send_indicator(&p->t38_gw_state.t38, T38_IND_NO_SIGNAL, p->t38_gw_state.t38.indicator_tx_count);
743 #endif
744         }
745
746         s->state = AST_FAX_STATE_ACTIVE;
747
748         return 0;
749 }
750
751 /*! \brief process a frame from the bridge
752  * \param s fax session
753  * \param f frame to process
754  * \return 1 on sucess 0 on incorect packet*/
755 static int spandsp_fax_gateway_process(struct ast_fax_session *s, const struct ast_frame *f)
756 {
757         struct spandsp_pvt *p = s->tech_pvt;
758
759         /*invalid frame*/
760         if (!f->data.ptr || !f->datalen) {
761                 return -1;
762         }
763
764         /* Process a IFP packet */
765         if ((f->frametype == AST_FRAME_MODEM) && (f->subclass.integer == AST_MODEM_T38)) {
766                 return t38_core_rx_ifp_packet(p->t38_core_state, f->data.ptr, f->datalen, f->seqno);
767         } else if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id == AST_FORMAT_SLINEAR)) {
768                 return t38_gateway_rx(&p->t38_gw_state, f->data.ptr, f->samples);
769         }
770
771         return -1;
772 }
773
774 /*! \brief gather data and clean up after gateway ends
775  * \param s fax session*/
776 static void spandsp_fax_gateway_cleanup(struct ast_fax_session *s)
777 {
778         struct spandsp_pvt *p = s->tech_pvt;
779         t38_stats_t t38_stats;
780
781         t38_gateway_get_transfer_statistics(&p->t38_gw_state, &t38_stats);
782
783         s->details->option.ecm = t38_stats.error_correcting_mode ? AST_FAX_OPTFLAG_TRUE : AST_FAX_OPTFLAG_FALSE;
784         s->details->pages_transferred = t38_stats.pages_transferred;
785         ast_string_field_build(s->details, transfer_rate, "%d", t38_stats.bit_rate);
786 }
787
788 /*! \brief */
789 static int spandsp_fax_start(struct ast_fax_session *s)
790 {
791         struct spandsp_pvt *p = s->tech_pvt;
792
793         s->state = AST_FAX_STATE_OPEN;
794
795         if (s->details->caps & AST_FAX_TECH_GATEWAY) {
796                 return spandsp_fax_gateway_start(s);
797         }
798
799         if (p->ist38) {
800 #if SPANDSP_RELEASE_DATE >= 20080725
801                 /* for spandsp shaphots 0.0.6 and higher */
802                 p->t30_state = &p->t38_state.t30;
803                 p->t38_core_state = &p->t38_state.t38_fe.t38;
804 #else
805                 /* for spandsp releases 0.0.5 */
806                 p->t30_state = &p->t38_state.t30_state;
807                 p->t38_core_state = &p->t38_state.t38;
808 #endif
809         } else {
810 #if SPANDSP_RELEASE_DATE >= 20080725
811                 /* for spandsp shaphots 0.0.6 and higher */
812                 p->t30_state = &p->fax_state.t30;
813 #else
814                 /* for spandsp release 0.0.5 */
815                 p->t30_state = &p->fax_state.t30_state;
816 #endif
817         }
818
819         set_logging(&p->t30_state->logging, s->details);
820
821         /* set some parameters */
822         set_local_info(p->t30_state, s->details);
823         set_file(p->t30_state, s->details);
824         set_ecm(p->t30_state, s->details);
825
826         /* perhaps set_transmit_on_idle() should be called */
827
828         t30_set_phase_e_handler(p->t30_state, t30_phase_e_handler, s);
829
830         /* set T.38 parameters */
831         if (p->ist38) {
832                 set_logging(&p->t38_core_state->logging, s->details);
833
834                 t38_set_max_datagram_size(p->t38_core_state, s->details->their_t38_parameters.max_ifp);
835
836                 if (s->details->their_t38_parameters.fill_bit_removal) {
837                         t38_set_fill_bit_removal(p->t38_core_state, TRUE);
838                 }
839
840                 if (s->details->their_t38_parameters.transcoding_mmr) {
841                         t38_set_mmr_transcoding(p->t38_core_state, TRUE);
842                 }
843
844                 if (s->details->their_t38_parameters.transcoding_jbig) {
845                         t38_set_jbig_transcoding(p->t38_core_state, TRUE);
846                 }
847         } else {
848                 /* have the fax stack generate silence if it has no data to send */
849                 fax_set_transmit_on_idle(&p->fax_state, 1);
850         }
851
852
853         /* start the timer */
854         if (ast_timer_set_rate(p->timer, SPANDSP_FAX_TIMER_RATE)) {
855                 ast_log(LOG_ERROR, "FAX session '%d' error setting rate on timing source.\n", s->id);
856                 return -1;
857         }
858
859         s->state = AST_FAX_STATE_ACTIVE;
860
861         return 0;
862 }
863
864 /*! \brief */
865 static int spandsp_fax_cancel(struct ast_fax_session *s)
866 {
867         struct spandsp_pvt *p = s->tech_pvt;
868
869         if (s->details->caps & AST_FAX_TECH_GATEWAY) {
870                 p->isdone = 1;
871                 return 0;
872         }
873
874         t30_terminate(p->t30_state);
875         p->isdone = 1;
876         return 0;
877 }
878
879 /*! \brief */
880 static int spandsp_fax_switch_to_t38(struct ast_fax_session *s)
881 {
882         struct spandsp_pvt *p = s->tech_pvt;
883
884         /* prevent the phase E handler from running, this is not a real termination */
885         t30_set_phase_e_handler(p->t30_state, NULL, NULL);
886
887         t30_terminate(p->t30_state);
888
889         s->details->option.switch_to_t38 = 1;
890         ast_atomic_fetchadd_int(&p->stats->switched, 1);
891
892         p->ist38 = 1;
893         p->stats = &spandsp_global_stats.t38;
894         spandsp_fax_start(s);
895
896         return 0;
897 }
898
899 /*! \brief */
900 static char *spandsp_fax_cli_show_capabilities(int fd)
901 {
902         ast_cli(fd, "SEND RECEIVE T.38 G.711 GATEWAY\n\n");
903         return  CLI_SUCCESS;
904 }
905
906 /*! \brief */
907 static char *spandsp_fax_cli_show_session(struct ast_fax_session *s, int fd)
908 {
909         struct spandsp_pvt *p = s->tech_pvt;
910
911         ao2_lock(s);
912         if (s->details->caps & AST_FAX_TECH_GATEWAY) {
913                 ast_cli(fd, "%-22s : %d\n", "session", s->id);
914                 ast_cli(fd, "%-22s : %s\n", "operation", "Gateway");
915                 ast_cli(fd, "%-22s : %s\n", "state", ast_fax_state_to_str(s->state));
916                 if (s->state != AST_FAX_STATE_UNINITIALIZED) {
917                         t38_stats_t stats;
918                         t38_gateway_get_transfer_statistics(&p->t38_gw_state, &stats);
919                         ast_cli(fd, "%-22s : %s\n", "ECM Mode", stats.error_correcting_mode ? "Yes" : "No");
920                         ast_cli(fd, "%-22s : %d\n", "Data Rate", stats.bit_rate);
921                         ast_cli(fd, "%-22s : %d\n", "Page Number", stats.pages_transferred + 1);
922                 }
923         } else {
924                 ast_cli(fd, "%-22s : %d\n", "session", s->id);
925                 ast_cli(fd, "%-22s : %s\n", "operation", (s->details->caps & AST_FAX_TECH_RECEIVE) ? "Receive" : "Transmit");
926                 ast_cli(fd, "%-22s : %s\n", "state", ast_fax_state_to_str(s->state));
927                 if (s->state != AST_FAX_STATE_UNINITIALIZED) {
928                         t30_stats_t stats;
929                         t30_get_transfer_statistics(p->t30_state, &stats);
930                         ast_cli(fd, "%-22s : %s\n", "Last Status", t30_completion_code_to_str(stats.current_status));
931                         ast_cli(fd, "%-22s : %s\n", "ECM Mode", stats.error_correcting_mode ? "Yes" : "No");
932                         ast_cli(fd, "%-22s : %d\n", "Data Rate", stats.bit_rate);
933                         ast_cli(fd, "%-22s : %dx%d\n", "Image Resolution", stats.x_resolution, stats.y_resolution);
934 #if SPANDSP_RELEASE_DATE >= 20090220
935                         ast_cli(fd, "%-22s : %d\n", "Page Number", ((s->details->caps & AST_FAX_TECH_RECEIVE) ? stats.pages_rx : stats.pages_tx) + 1);
936 #else
937                         ast_cli(fd, "%-22s : %d\n", "Page Number", stats.pages_transferred + 1);
938 #endif
939                         ast_cli(fd, "%-22s : %s\n", "File Name", s->details->caps & AST_FAX_TECH_RECEIVE ? p->t30_state->rx_file : p->t30_state->tx_file);
940
941                         ast_cli(fd, "\nData Statistics:\n");
942 #if SPANDSP_RELEASE_DATE >= 20090220
943                         ast_cli(fd, "%-22s : %d\n", "Tx Pages", stats.pages_tx);
944                         ast_cli(fd, "%-22s : %d\n", "Rx Pages", stats.pages_rx);
945 #else
946                         ast_cli(fd, "%-22s : %d\n", "Tx Pages", (s->details->caps & AST_FAX_TECH_SEND) ? stats.pages_transferred : 0);
947                         ast_cli(fd, "%-22s : %d\n", "Rx Pages", (s->details->caps & AST_FAX_TECH_RECEIVE) ? stats.pages_transferred : 0);
948 #endif
949                         ast_cli(fd, "%-22s : %d\n", "Longest Bad Line Run", stats.longest_bad_row_run);
950                         ast_cli(fd, "%-22s : %d\n", "Total Bad Lines", stats.bad_rows);
951                 }
952         }
953         ao2_unlock(s);
954         ast_cli(fd, "\n\n");
955         return CLI_SUCCESS;
956 }
957
958 /*! \brief */
959 static char *spandsp_fax_cli_show_stats(int fd)
960 {
961         ast_mutex_lock(&spandsp_global_stats.lock);
962         ast_cli(fd, "\n%-20.20s\n", "Spandsp G.711");
963         ast_cli(fd, "%-20.20s : %d\n", "Success", spandsp_global_stats.g711.success);
964         ast_cli(fd, "%-20.20s : %d\n", "Switched to T.38", spandsp_global_stats.g711.switched);
965         ast_cli(fd, "%-20.20s : %d\n", "Call Dropped", spandsp_global_stats.g711.call_dropped);
966         ast_cli(fd, "%-20.20s : %d\n", "No FAX", spandsp_global_stats.g711.nofax);
967         ast_cli(fd, "%-20.20s : %d\n", "Negotiation Failed", spandsp_global_stats.g711.neg_failed);
968         ast_cli(fd, "%-20.20s : %d\n", "Train Failure", spandsp_global_stats.g711.failed_to_train);
969         ast_cli(fd, "%-20.20s : %d\n", "Retries Exceeded", spandsp_global_stats.g711.retries_exceeded);
970         ast_cli(fd, "%-20.20s : %d\n", "Protocol Error", spandsp_global_stats.g711.protocol_error);
971         ast_cli(fd, "%-20.20s : %d\n", "TX Protocol Error", spandsp_global_stats.g711.tx_protocol_error);
972         ast_cli(fd, "%-20.20s : %d\n", "RX Protocol Error", spandsp_global_stats.g711.rx_protocol_error);
973         ast_cli(fd, "%-20.20s : %d\n", "File Error", spandsp_global_stats.g711.file_error);
974         ast_cli(fd, "%-20.20s : %d\n", "Memory Error", spandsp_global_stats.g711.mem_error);
975         ast_cli(fd, "%-20.20s : %d\n", "Unknown Error", spandsp_global_stats.g711.unknown_error);
976
977         ast_cli(fd, "\n%-20.20s\n", "Spandsp T.38");
978         ast_cli(fd, "%-20.20s : %d\n", "Success", spandsp_global_stats.t38.success);
979         ast_cli(fd, "%-20.20s : %d\n", "Call Dropped", spandsp_global_stats.t38.call_dropped);
980         ast_cli(fd, "%-20.20s : %d\n", "No FAX", spandsp_global_stats.t38.nofax);
981         ast_cli(fd, "%-20.20s : %d\n", "Negotiation Failed", spandsp_global_stats.t38.neg_failed);
982         ast_cli(fd, "%-20.20s : %d\n", "Train Failure", spandsp_global_stats.t38.failed_to_train);
983         ast_cli(fd, "%-20.20s : %d\n", "Retries Exceeded", spandsp_global_stats.t38.retries_exceeded);
984         ast_cli(fd, "%-20.20s : %d\n", "Protocol Error", spandsp_global_stats.t38.protocol_error);
985         ast_cli(fd, "%-20.20s : %d\n", "TX Protocol Error", spandsp_global_stats.t38.tx_protocol_error);
986         ast_cli(fd, "%-20.20s : %d\n", "RX Protocol Error", spandsp_global_stats.t38.rx_protocol_error);
987         ast_cli(fd, "%-20.20s : %d\n", "File Error", spandsp_global_stats.t38.file_error);
988         ast_cli(fd, "%-20.20s : %d\n", "Memory Error", spandsp_global_stats.t38.mem_error);
989         ast_cli(fd, "%-20.20s : %d\n", "Unknown Error", spandsp_global_stats.t38.unknown_error);
990         ast_mutex_unlock(&spandsp_global_stats.lock);
991
992         return CLI_SUCCESS;
993 }
994
995 /*! \brief Show res_fax_spandsp settings */
996 static char *spandsp_fax_cli_show_settings(int fd)
997 {
998         /* no settings at the moment */
999         return CLI_SUCCESS;
1000 }
1001
1002 /*! \brief unload res_fax_spandsp */
1003 static int unload_module(void)
1004 {
1005         ast_fax_tech_unregister(&spandsp_fax_tech);
1006         ast_mutex_destroy(&spandsp_global_stats.lock);
1007         return AST_MODULE_LOAD_SUCCESS;
1008 }
1009
1010 /*! \brief load res_fax_spandsp */
1011 static int load_module(void)
1012 {
1013         ast_mutex_init(&spandsp_global_stats.lock);
1014         spandsp_fax_tech.module = ast_module_info->self;
1015         if (ast_fax_tech_register(&spandsp_fax_tech) < 0) {
1016                 ast_log(LOG_ERROR, "failed to register FAX technology\n");
1017                 return AST_MODULE_LOAD_DECLINE;
1018         }
1019
1020         /* prevent logging to stderr */
1021         span_set_message_handler(NULL);
1022
1023         return AST_MODULE_LOAD_SUCCESS;
1024 }
1025
1026
1027 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Spandsp G.711 and T.38 FAX Technologies",
1028                 .load = load_module,
1029                 .unload = unload_module,
1030                );