~ubuntu-branches/ubuntu/quantal/asterisk/quantal

« back to all changes in this revision

Viewing changes to apps/app_fax.c

  • Committer: Bazaar Package Importer
  • Author(s): Jean-Michel Dault
  • Date: 2010-02-16 14:08:54 UTC
  • mfrom: (1.2.5 upstream) (8.3.4 sid)
  • Revision ID: james.westby@ubuntu.com-20100216140854-rb2godspb9lduazl
Tags: 1:1.6.2.2-1ubuntu1
* Merge from Debian: security update
  * Changes:
  - debian/control: Change Maintainer
  - debian/control: Removed Uploaders field.
  - debian/control: Removed Debian Vcs-Svn entry and replaced with
      ubuntu-voip Vcs-Bzr, to reflect divergence in packages.
  - debian/asterisk.init : chown /dev/dahdi
  - debian/backports/hardy : add file
  - debian/backports/asterisk.init.hardy : add file

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
#include "asterisk.h"
20
20
 
21
 
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 209282 $")
 
21
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 235013 $")
22
22
 
23
23
#include <string.h>
24
24
#include <stdlib.h>
372
372
        enum ast_t38_state t38_state;
373
373
        struct ast_control_t38_parameters t38_parameters = { .version = 0,
374
374
                                                             .max_ifp = 800,
375
 
                                                             .rate = AST_T38_RATE_9600,
 
375
                                                             .rate = AST_T38_RATE_14400,
376
376
                                                             .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
377
377
                                                             .fill_bit_removal = 1,
378
378
                                                             .transcoding_mmr = 1,
379
379
                                                             .transcoding_jbig = 1,
380
380
        };
381
381
 
382
 
        /* if in receive mode, try to use T.38 */
383
 
        if (!s->direction) {
 
382
        /* if in called party mode, try to use T.38 */
 
383
        if (s->caller_mode == FALSE) {
384
384
                /* check if we are already in T.38 mode (unlikely), or if we can request
385
385
                 * a switch... if so, request it now and wait for the result, rather
386
386
                 * than starting an audio FAX session that will have to be cancelled
492
492
        while (!s->finished) {
493
493
                inf = NULL;
494
494
 
495
 
                if ((res = ast_waitfor(s->chan, 20)) < 0) {
496
 
                        break;
497
 
                }
498
 
 
499
 
                /* if nothing arrived, check the watchdog timers */
500
 
                if (res == 0) {
501
 
                        now = ast_tvnow();
502
 
                        if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
503
 
                                ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
504
 
                                res = -1;
505
 
                                break;
506
 
                        } else {
507
 
                                /* timers have not triggered, loop around to wait
508
 
                                 * again
509
 
                                 */
510
 
                                continue;
511
 
                        }
512
 
                }
 
495
                if ((res = ast_waitfor(s->chan, 25)) < 0) {
 
496
                        ast_debug(1, "Error waiting for a frame\n");
 
497
                        break;
 
498
                }
 
499
 
 
500
                /* Watchdog */
 
501
                now = ast_tvnow();
 
502
                if (ast_tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || ast_tvdiff_sec(now, state_change) > WATCHDOG_STATE_TIMEOUT) {
 
503
                        ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
 
504
                        res = -1;
 
505
                        break;
 
506
                }
 
507
 
 
508
                if (!res) {
 
509
                        /* There was timeout waiting for a frame. Loop around and wait again */
 
510
                        continue;
 
511
                }
 
512
 
 
513
                /* There is a frame available. Get it */
 
514
                res = 0;
513
515
 
514
516
                if (!(inf = ast_read(s->chan))) {
515
517
                        ast_debug(1, "Channel hangup\n");
613
615
        memset(&t38, 0, sizeof(t38));
614
616
        if (t38_terminal_init(&t38, s->caller_mode, t38_tx_packet_handler, s->chan) == NULL) {
615
617
                ast_log(LOG_WARNING, "Unable to start T.38 termination.\n");
616
 
                return -1;
 
618
                res = -1;
 
619
                goto disable_t38;
617
620
        }
618
621
 
619
622
        t38_set_max_datagram_size(t38state, s->t38parameters.max_ifp);
700
703
        t30_terminate(t30state);
701
704
        t38_terminal_release(&t38);
702
705
 
 
706
disable_t38:
 
707
        /* if we are not the caller, it's our job to shut down the T.38
 
708
         * session when the FAX transmisson is complete.
 
709
         */
 
710
        if ((s->caller_mode == FALSE) &&
 
711
            (ast_channel_get_t38_state(s->chan) == T38_STATE_NEGOTIATED)) {
 
712
                struct ast_control_t38_parameters t38_parameters = { .request_response = AST_T38_REQUEST_TERMINATE, };
 
713
 
 
714
                if (ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &t38_parameters, sizeof(t38_parameters)) == 0) {
 
715
                        /* wait up to five seconds for negotiation to complete */
 
716
                        unsigned int timeout = 5000;
 
717
                        int ms;
 
718
                        
 
719
                        ast_debug(1, "Shutting down T.38 on %s\n", s->chan->name);
 
720
                        while (timeout > 0) {
 
721
                                ms = ast_waitfor(s->chan, 1000);
 
722
                                if (ms < 0) {
 
723
                                        ast_log(LOG_WARNING, "something bad happened while channel '%s' was polling.\n", s->chan->name);
 
724
                                        return -1;
 
725
                                }
 
726
                                if (!ms) {
 
727
                                        /* nothing happened */
 
728
                                        if (timeout > 0) {
 
729
                                                timeout -= 1000;
 
730
                                                continue;
 
731
                                        } else {
 
732
                                                ast_log(LOG_WARNING, "channel '%s' timed-out during the T.38 shutdown.\n", s->chan->name);
 
733
                                                break;
 
734
                                        }
 
735
                                }
 
736
                                if (!(inf = ast_read(s->chan))) {
 
737
                                        return -1;
 
738
                                }
 
739
                                if ((inf->frametype == AST_FRAME_CONTROL) &&
 
740
                                    (inf->subclass == AST_CONTROL_T38_PARAMETERS) &&
 
741
                                    (inf->datalen == sizeof(t38_parameters))) {
 
742
                                        struct ast_control_t38_parameters *parameters = inf->data.ptr;
 
743
                                        
 
744
                                        switch (parameters->request_response) {
 
745
                                        case AST_T38_TERMINATED:
 
746
                                                ast_debug(1, "Shut down T.38 on %s\n", s->chan->name);
 
747
                                                break;
 
748
                                        case AST_T38_REFUSED:
 
749
                                                ast_log(LOG_WARNING, "channel '%s' refused to disable T.38\n", s->chan->name);
 
750
                                                break;
 
751
                                        default:
 
752
                                                ast_log(LOG_ERROR, "channel '%s' failed to disable T.38\n", s->chan->name);
 
753
                                                break;
 
754
                                        }
 
755
                                        ast_frfree(inf);
 
756
                                        break;
 
757
                                }
 
758
                                ast_frfree(inf);
 
759
                        }
 
760
                }
 
761
        }
 
762
 
703
763
        return res;
704
764
}
705
765