]> git.pld-linux.org Git - packages/asterisk.git/blob - app_rxfax.c
462f306ae843d77a153b6da95b9375e242be7e60
[packages/asterisk.git] / app_rxfax.c
1 /*
2  * Application to receive a TIFF FAX file
3  * based on app_rxfax.c from: Copyright (C) 2003, Steve Underwood <steveu@coppice.org>
4  * based on app_rxfax.c from www.callweaver.org
5  * PATCHED BY (C) 20007 by Antonio Gallo <agx@linux.it>
6  * - added ECM support
7  * - added more env variables
8  *
9  */
10
11 /*** MODULEINFO
12 Depends: libspandsp
13 Desciption: Receive a FAX to a file
14 DisplayName: RxFAX
15  ***/
16
17 #include "asterisk.h"
18
19 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
20
21 #include <string.h>
22 #include <stdarg.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
30 #include <spandsp.h>
31 #include <spandsp/version.h>
32
33 #include "asterisk/lock.h"
34 #include "asterisk/file.h"
35 #include "asterisk/logger.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/module.h"
39 #include "asterisk/manager.h"
40
41 #ifndef AST_MODULE
42 #define AST_MODULE "app_rxfax"
43 #endif
44
45 static char *app = "RxFAX";
46
47 static char *synopsis = "Receive a FAX to a file";
48
49 static char *descrip = 
50         "  RxFAX(filename[|caller][|debug]): Receives a FAX from the channel into the\n"
51         "given filename. If the file exists it will be overwritten. The file\n"
52         "should be in TIFF/F format.\n"
53         "The \"caller\" option makes the application behave as a calling machine,\n"
54         "rather than the answering machine. The default behaviour is to behave as\n"
55         "an answering machine.\n"
56         "The \"ecm\" option enables ECM.\n"
57         "Uses LOCALSTATIONID to identify itself to the remote end.\n"
58         "     LOCALSUBADDRESS to specify a sub-address to the remote end.\n"
59         "     LOCALHEADERINFO to generate a header line on each page.\n"
60
61         "     FAX_FORCE_V17 to force V.17 only\n"
62         "     FAX_FORCE_V27 to force V.27 only\n"
63         "     FAX_FORCE_V29 to force V.29 only\n"
64         "     FAX_FORCE_V34 to force V.34 only\n"
65
66         "Sets REMOTESTATIONID to the sender CSID.\n"
67         "     FAXPAGES to the number of pages received.\n"
68         "     FAXBITRATE to the transmition rate.\n"
69         "     FAXRESOLUTION to the resolution.\n"
70         "     PHASEESTATUS to the phase E result status.\n"
71         "     PHASEESTRING to the phase E result string.\n"
72         "Note that PHASEESTATUS=0 means that the fax was handled correctly. But that doesn't\n"
73         "imply that any pages were sent. Actually you should also check FAXPAGES to be\n"
74         "greater than zero.\n"
75         "Returns -1 when the user hangs up.\n"
76         "Returns 0 otherwise.\n";
77
78 #define MAX_BLOCK_SIZE 240
79
80 static FILE *rxfax_logfile = NULL;
81
82 static void file_log(const char *msg)
83 {
84         if (msg==NULL) 
85                 return;
86         if (rxfax_logfile==NULL)
87                 return;
88         fprintf(rxfax_logfile, msg);
89 }
90
91 static void span_message(int level, const char *msg)
92 {
93         if (msg==NULL) return;
94         int ast_level;
95         if (level == SPAN_LOG_ERROR)
96                 ast_level = __LOG_ERROR;
97         else if (level == SPAN_LOG_WARNING)
98                 ast_level = __LOG_WARNING;
99         else
100                 ast_level = __LOG_DEBUG;
101         ast_log(ast_level, _A_, "%s", msg);
102         file_log(msg);
103 }
104
105 /*- End of function --------------------------------------------------------*/
106
107 static int phase_b_handler(t30_state_t *s, void *user_data, int result)
108 {
109         if (rxfax_logfile!=NULL) {
110                 fprintf( rxfax_logfile, "[phase_b_handler] mark\n" );
111                 fflush(rxfax_logfile);
112         }
113         return T30_ERR_OK;
114 }
115
116 /*- End of function --------------------------------------------------------*/
117 static void phase_e_handler(t30_state_t *s, void *user_data, int result)
118 {
119         struct ast_channel *chan;
120         const char *tx_ident;
121         const char *rx_ident;
122         char buf[128];
123         t30_stats_t t;
124
125         chan = (struct ast_channel *) user_data;
126         t30_get_transfer_statistics(s, &t);
127
128         tx_ident = t30_get_tx_ident(s);
129         if (tx_ident == NULL)
130                 tx_ident = "";
131         rx_ident = t30_get_rx_ident(s);
132         if (rx_ident == NULL)
133                 rx_ident = "";
134         pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", rx_ident);
135         snprintf(buf, sizeof(buf), "%d", t.pages_transferred);
136         pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
137         snprintf(buf, sizeof(buf), "%d", t.y_resolution);
138         pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", buf);
139         snprintf(buf, sizeof(buf), "%d", t.bit_rate);
140         pbx_builtin_setvar_helper(chan, "FAXBITRATE", buf);
141         snprintf(buf, sizeof(buf), "%d", result);
142         pbx_builtin_setvar_helper(chan, "PHASEESTATUS", buf);
143         snprintf(buf, sizeof(buf), "%s", t30_completion_code_to_str(result));
144         pbx_builtin_setvar_helper(chan, "PHASEESTRING", buf);
145
146         ast_log(LOG_DEBUG, "==============================================================================\n");
147         if (result == T30_ERR_OK)
148         {
149                 ast_log(LOG_DEBUG, "Fax successfully received.\n");
150                 ast_log(LOG_DEBUG, "Remote station id: %s\n", rx_ident);
151                 ast_log(LOG_DEBUG, "Local station id:  %s\n", tx_ident);
152                 ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
153                 ast_log(LOG_DEBUG, "Image resolution:  %i x %i\n", t.x_resolution, t.y_resolution);
154                 ast_log(LOG_DEBUG, "Transfer Rate:     %i\n", t.bit_rate);
155                 manager_event(EVENT_FLAG_CALL,
156                                 "FaxReceived", "Channel: %s\nExten: %s\nCallerID: %s\nRemoteStationID: %s\nLocalStationID: %s\nPagesTransferred: %i\nResolution: %i\nTransferRate: %i\nFileName: %s\n",
157                                 chan->name,
158                                 chan->exten,
159                                 (chan->cid.cid_num)  ?  chan->cid.cid_num  :  "",
160                                 rx_ident,
161                                 tx_ident,
162                                 t.pages_transferred,
163                                 t.y_resolution,
164                                 t.bit_rate,
165                                 s->rx_file);
166                 if (rxfax_logfile!=NULL) {
167                         fprintf( rxfax_logfile, "\n[FAX OK] Remote: %s Local: %s Pages: %i Speed: %i\n\n", 
168                                 rx_ident, tx_ident, t.pages_transferred, t.bit_rate
169                         );
170                         fflush(rxfax_logfile);
171                 }
172         }
173         else
174         {
175                 ast_log(LOG_DEBUG, "Fax receive not successful - result (%d) %s.\n", result, t30_completion_code_to_str(result));
176                 if (rxfax_logfile!=NULL) {
177                         fprintf( rxfax_logfile, "\n[FAX ERROR] code: %d %s\n\n", result, t30_completion_code_to_str(result) );
178                         fflush(rxfax_logfile);
179                 }
180         }
181         ast_log(LOG_DEBUG, "==============================================================================\n");
182 }
183 /*- End of function --------------------------------------------------------*/
184
185 static int phase_d_handler(t30_state_t *s, void *user_data, int result)
186 {
187         struct ast_channel *chan;
188         t30_stats_t t;
189
190         chan = (struct ast_channel *) user_data;
191         if (result)
192         {
193                 t30_get_transfer_statistics(s, &t);
194                 ast_log(LOG_DEBUG, "==============================================================================\n");
195                 ast_log(LOG_DEBUG, "Pages transferred:  %i\n", t.pages_transferred);
196                 ast_log(LOG_DEBUG, "Image size:         %i x %i\n", t.width, t.length);
197                 ast_log(LOG_DEBUG, "Image resolution    %i x %i\n", t.x_resolution, t.y_resolution);
198                 ast_log(LOG_DEBUG, "Transfer Rate:      %i\n", t.bit_rate);
199                 ast_log(LOG_DEBUG, "Bad rows            %i\n", t.bad_rows);
200                 ast_log(LOG_DEBUG, "Longest bad row run %i\n", t.longest_bad_row_run);
201                 ast_log(LOG_DEBUG, "Compression type    %s\n", t4_encoding_to_str(t.encoding));
202                 ast_log(LOG_DEBUG, "Image size (bytes)  %i\n", t.image_size);
203                 ast_log(LOG_DEBUG, "==============================================================================\n");
204                 if (rxfax_logfile!=NULL) {
205                         fprintf( rxfax_logfile, "\n[phase_d_handler] Page: %i at %i\n\n",  t.pages_transferred, t.bit_rate );
206                         fflush(rxfax_logfile);
207                 }
208         }
209     return T30_ERR_OK;
210 }
211 /*- End of function --------------------------------------------------------*/
212
213 static int rxfax_exec(struct ast_channel *chan, void *data)
214 {
215         int res = 0;
216         char target_file[256];
217         char template_file[256];
218         int samples;
219         char *s;
220         char *t;
221         char *v;
222         const char *x;
223         int option;
224         int len;
225         int i;
226         fax_state_t fax;
227         struct ast_frame *inf = NULL;
228         struct ast_frame outf;
229         int calling_party;
230         int verbose;
231         int ecm = FALSE;
232
233         struct ast_module_user *u;
234
235         int original_read_fmt;
236         int original_write_fmt;
237
238
239         /* Basic initial checkings */
240
241         if (chan == NULL) {
242                 ast_log(LOG_WARNING, "Fax receive channel is NULL. Giving up.\n");
243                 file_log("FATAL ERROR: Fax receive channel is NULL. Giving up.\n");
244                 return -1;
245         }
246
247         //span_set_message_handler(span_message);
248         /* make sure they are initialized to zero */
249         memset( &fax, 0, sizeof(fax));
250
251         /* Resetting channel variables related to T38 */
252         pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", "");
253         pbx_builtin_setvar_helper(chan, "FAXPAGES", "");
254         pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", "");
255         pbx_builtin_setvar_helper(chan, "FAXBITRATE", "");
256         pbx_builtin_setvar_helper(chan, "PHASEESTATUS", "");
257         pbx_builtin_setvar_helper(chan, "PHASEESTRING", "");
258
259         /* Parsig parameters */
260
261         /* The next few lines of code parse out the filename and header from the input string */
262         if (data == NULL)
263         {
264                 /* No data implies no filename or anything is present */
265                 ast_log(LOG_WARNING, "Rxfax requires an argument (filename)\n");
266                 file_log("ERROR: Rxfax requires an argument (filename)\n");
267                 return -1;
268         }
269
270         calling_party = FALSE;
271         verbose = FALSE;
272         target_file[0] = '\0';
273
274         char tbuf[256];
275         for (option = 0, v = s = data;  v;  option++, s++) {
276                 t = s;
277                 v = strchr(s, '|');
278                 s = (v)  ?  v  :  s + strlen(s);
279                 strncpy((char *) tbuf, t, s - t);
280                 tbuf[s - t] = '\0';
281                 if (option == 0) {
282                         /* The first option is always the file name */
283                         len = s - t;
284                         if (len > 255)
285                                 len = 255;
286                         strncpy(target_file, t, len);
287                         target_file[len] = '\0';
288                         /* Allow the use of %d in the file name for a wild card of sorts, to
289                            create a new file with the specified name scheme */
290                         if ((x = strchr(target_file, '%'))  &&  x[1] == 'd') {
291                                 strcpy(template_file, target_file);
292                                 i = 0;
293                                 do {
294                                         snprintf(target_file, 256, template_file, 1);
295                                         i++;
296                                 } while (ast_fileexists(target_file, "", chan->language) != -1);
297                         }
298                 } else if (strncmp("caller", t, s - t) == 0) {
299                         calling_party = TRUE;
300                 } else if (strncmp("debug", t, s - t) == 0) {
301                         verbose = TRUE;
302                 } else if (strncmp("ecm", t, s - t) == 0) {
303                         ecm = TRUE;
304                 }
305         }
306
307         /* Done parsing */
308
309         u = ast_module_user_add(chan);
310
311         if (chan->_state != AST_STATE_UP)
312         {
313                 /* Shouldn't need this, but checking to see if channel is already answered
314                  * Theoretically the PBX should already have answered before running the app */
315                 res = ast_answer(chan);
316                 /* NO NEED TO WARN ANYMORE 
317                 if (!res)
318                 {
319                         ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
320                         file_log("Could not answer channel\n" );
321                 }
322                 */
323         }
324
325         /* Setting read and write formats */
326
327         original_read_fmt = chan->readformat;
328         if (original_read_fmt != AST_FORMAT_SLINEAR)
329         {
330                 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
331                 if (res < 0)
332                 {
333                         ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
334                         file_log("ERROR: Unable to set to linear read mode, giving up\n");
335                         ast_module_user_remove(u);
336                         return -1;
337                 }
338         }
339
340         original_write_fmt = chan->writeformat;
341         if (original_write_fmt != AST_FORMAT_SLINEAR)
342         {
343                 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
344                 if (res < 0)
345                 {
346                         ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
347                         file_log("ERROR: Unable to set to linear write mode, giving up\n");
348                         res = ast_set_read_format(chan, original_read_fmt);
349                         if (res)
350                                 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
351                         ast_module_user_remove(u);
352                         return -1;
353                 }
354         }
355
356         /* Remove any app level gain adjustments and disable echo cancel. */
357         signed char sc;
358         sc = 0;
359         ast_channel_setoption(chan, AST_OPTION_RXGAIN, &sc, sizeof(sc), 0);
360         ast_channel_setoption(chan, AST_OPTION_TXGAIN, &sc, sizeof(sc), 0);
361         ast_channel_setoption(chan, AST_OPTION_ECHOCAN, &sc, sizeof(sc), 0);
362
363         /* This is the main loop */
364
365         uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET];
366         uint8_t *buf = __buf + AST_FRIENDLY_OFFSET;
367
368         memset(&fax, 0, sizeof(fax));
369
370         if (fax_init(&fax, calling_party) == NULL)
371         {
372                 ast_log(LOG_WARNING, "Unable to set to start fax_init\n");
373                 file_log("ERROR: Unable to set to start fax_init\n");
374                 ast_module_user_remove(u);
375                 return -1;
376         }
377         fax_set_transmit_on_idle(&fax, TRUE);
378         span_log_set_message_handler(&fax.logging, span_message);
379         span_log_set_message_handler(&fax.t30_state.logging, span_message);
380         if (verbose)
381         {
382                 span_log_set_level(&fax.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
383                 span_log_set_level(&fax.t30_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
384         }
385         x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
386         if (x  &&  x[0])
387                 t30_set_tx_ident(&fax.t30_state, x);
388         x = pbx_builtin_getvar_helper(chan, "LOCALSUBADDRESS");
389         if (x  &&  x[0])
390                 t30_set_tx_sub_address(&fax.t30_state, x);
391         x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO");
392         if (x  &&  x[0])
393                 t30_set_tx_page_header_info(&fax.t30_state, x);
394         t30_set_rx_file(&fax.t30_state, target_file, -1);
395         t30_set_phase_b_handler(&fax.t30_state, phase_b_handler, chan);
396         t30_set_phase_d_handler(&fax.t30_state, phase_d_handler, chan);
397         t30_set_phase_e_handler(&fax.t30_state, phase_e_handler, chan);
398
399         // Default Support ALL
400         t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29 | T30_SUPPORT_V27TER | T30_SUPPORT_V17 );
401
402         x = pbx_builtin_getvar_helper(chan, "FAX_DISABLE_V17");
403         if (x  &&  x[0])
404                 t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
405
406         x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V17");
407         if (x  &&  x[0])
408                 t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V17);
409         x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V27");
410         if (x  &&  x[0])
411                 t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V27TER);
412         x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V29");
413         if (x  &&  x[0])
414                 t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29);
415         x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V34");
416         if (x  &&  x[0])
417                 t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V34);
418
419         /* Support for different image sizes && resolutions*/
420         t30_set_supported_image_sizes(&fax.t30_state, T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
421                         | T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH | T30_SUPPORT_303MM_WIDTH);
422         t30_set_supported_resolutions(&fax.t30_state, T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION
423                         | T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
424         if (ecm) {
425                 t30_set_ecm_capability(&(fax.t30_state), TRUE);
426                 t30_set_supported_compressions(&(fax.t30_state), T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
427                 ast_log(LOG_DEBUG, "Enabling ECM mode for app_rxfax\n"  );
428                 file_log("DEBUG: Enabling ECM mode for app_rxfax\n"  );
429         } else {
430                 t30_set_ecm_capability(&(fax.t30_state), FALSE);
431                 t30_set_supported_compressions(&(fax.t30_state), T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION );
432         }
433
434
435         /* This is the main loop */
436
437         res = 0;
438
439         /* temporary workwaround vars */
440         int donotspam=10;
441         int watchdog=256;
442
443         while ( chan )
444         {
445                 if (ast_check_hangup(chan)) {
446                         ast_log(LOG_WARNING, "Channel has been hanged at fax.\n");
447                         file_log("INFO: Channel has been hanged at fax.\n");
448                         res = 0;
449                         break;
450                 }
451
452                 if ((res = ast_waitfor(chan, 20)) < 0) {
453                         ast_log(LOG_WARNING, "Channel ast_waitfor < 0.\n");
454                         file_log("WARNING: Channel ast_waitfor < 0.\n");
455                         res = 0;
456                         break;
457                 }
458
459                 if ((fax.current_rx_type == T30_MODEM_DONE)  ||  (fax.current_tx_type == T30_MODEM_DONE)) {
460                         /* Avoid spamming debug info */
461                         if (donotspam>0) {
462                                 ast_log(LOG_WARNING, "Channel T30 DONE < 0.\n");
463                                 file_log("DEBUG: Channel T30 DONE.\n");
464                                 donotspam--;
465                         }
466                         /*
467                          * NOTE: if i break here it seems to have bad behavios on some faxes that
468                          * will not result as successfull send even if it has benn fully received
469                          */
470 /*JUST WARNING:         res = 0;
471                         break;*/
472                         /* 
473                          * Workaround: let 256 more packet to pass thru then definitively hangup
474                          */
475                         if (watchdog>0) {
476                                 watchdog--;
477                         } else {
478                                 break;
479                         }
480                 }
481
482                 inf = ast_read(chan);
483                 if (inf == NULL)
484                 {
485                         ast_log(LOG_WARNING, "Channel INF is NULL.\n");
486                         file_log("DEBUG: Channel INF is NULL.\n");
487
488                         // While trasmiitting i got: Received a DCN from remote after sending a page
489                         // at last page
490                         continue;
491                         //res = 0;
492                         //break;
493                 }
494
495                 /* We got a frame */
496                 //if (inf->frametype == AST_FRAME_VOICE) {
497                 /* Check the frame type. Format also must be checked because there is a chance
498                    that a frame in old format was already queued before we set chanel format
499                    to slinear so it will still be received by ast_read */
500                 if (inf->frametype == AST_FRAME_VOICE && inf->subclass == AST_FORMAT_SLINEAR) {
501                         if (fax_rx(&fax, inf->data, inf->samples)) {
502                                 ast_log(LOG_WARNING, "RXFAX: fax_rx returned error\n");
503                                 res = -1;
504                                 break;
505                         }
506
507                         samples = (inf->samples <= MAX_BLOCK_SIZE) ? inf->samples : MAX_BLOCK_SIZE;
508                         len = fax_tx(&fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples);
509                         if (len>0) {
510                                 /*if (len <= 0) {
511                                         ast_log(LOG_WARNING, "len <=0 using samples.\n");
512                                         file_log("len <= 0 using samples.\n");
513                                         len = samples;
514                                 }*/
515                                 memset(&outf, 0, sizeof(outf));
516                                 outf.frametype = AST_FRAME_VOICE;
517                                 outf.subclass = AST_FORMAT_SLINEAR;
518                                 outf.datalen = len*sizeof(int16_t);
519                                 outf.samples = len;
520                                 outf.data = &buf[AST_FRIENDLY_OFFSET];
521                                 outf.offset = AST_FRIENDLY_OFFSET;
522                                 outf.src = "RxFAX";
523                                 /*if (len <= 0) {
524                                         memset(&buf[AST_FRIENDLY_OFFSET], 0, outf.datalen);
525                                 }*/
526                                 if (ast_write(chan, &outf) < 0)
527                                 {
528                                         ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
529                                         file_log("ERROR: Unable to write frame to channel\n");
530                                         res = -1;
531                                         break;
532                                 }
533                         }
534                 }
535                 ast_frfree(inf);
536                 inf = NULL;
537                 /* TODO put a Watchdog here */
538         }
539
540         if (inf != NULL)
541         {
542                 ast_frfree(inf);
543                 inf = NULL;
544         }
545
546         t30_terminate(&fax.t30_state);
547         fax_release(&fax);
548
549         /* Restoring initial channel formats. */
550
551         if (original_read_fmt != AST_FORMAT_SLINEAR)
552         {
553                 res = ast_set_read_format(chan, original_read_fmt);
554                 if (res)
555                         ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
556         }
557         if (original_write_fmt != AST_FORMAT_SLINEAR)
558         {
559                 res = ast_set_write_format(chan, original_write_fmt);
560                 if (res)
561                         ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name);
562         }
563         ast_module_user_remove(u);
564         return res;
565 }
566 /*- End of function --------------------------------------------------------*/
567
568 static int unload_module(void)
569 {
570         int res;
571         ast_module_user_hangup_all();
572         res = ast_unregister_application(app);  
573         if (rxfax_logfile) {
574                 fclose(rxfax_logfile);
575                 rxfax_logfile = NULL;
576         }
577         return res;
578 }
579 /*- End of function --------------------------------------------------------*/
580
581 static int load_module(void)
582 {
583         ast_log(LOG_NOTICE, "RxFax using spandsp %i %i\n", SPANDSP_RELEASE_DATE, SPANDSP_RELEASE_TIME );
584         rxfax_logfile = fopen("/var/log/rxfax.log", "w+" );
585         if (rxfax_logfile)
586                 ast_log(LOG_WARNING, "RxFax output also available in /var/log/rxfax.log\n" );
587         return ast_register_application(app, rxfax_exec, synopsis, descrip);
588 }
589 /*- End of function --------------------------------------------------------*/
590
591 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Trivial FAX Receive Application");
592
593 /*- End of file ------------------------------------------------------------*/
This page took 0.596958 seconds and 2 git commands to generate.