⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ltmodem.c,v

📁 话带数据中传真解调程序
💻 C,V
📖 第 1 页 / 共 4 页
字号:
head	1.7;access;symbols;locks	root:1.7; strict;comment	@ * @;1.7date	99.12.19.21.52.09;	author root;	state Exp;branches;next	1.6;1.6date	99.12.01.04.11.43;	author root;	state Exp;branches;next	1.5;1.5date	99.08.22.03.35.38;	author root;	state Exp;branches;next	1.4;1.4date	99.08.16.02.59.21;	author root;	state Exp;branches;next	1.3;1.3date	99.07.21.03.30.34;	author root;	state Exp;branches;next	1.2;1.2date	99.07.05.04.04.46;	author root;	state Exp;branches;next	1.1;1.1date	99.07.05.03.51.18;	author root;	state Exp;branches;next	;desc@@1.7log@Checked back in prior to adding interrupt stuff, part of 0.9.6 build.@text@/*
 *	$Id: ltmodem.c,v 1.6 1999/12/01 04:11:43 root Exp $
 *
 *	Lucent modem diagnostics tool.
 *
 *  Copyright (c) 1999 Richard J.M. Close
 *  Copyright (c) 1999 Pavel Machek <pavel@@ucw.cz>
 *  Copyright (c) 1999 Jamie Lokier
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include "ltmodem.h"

unsigned int portbase;
unsigned int modem_irq;

// Main program.

int main(int argc, char **argv)
{

  char c;
  sync();	// it's for your own protection!
  setvbuf(stdout, NULL, _IONBF, 0);

  puts("ltmodem version " LTMODEM_VERSION);

#if LT_ISAPNP
  init_isa();
#else
  init_pci();
#endif

  /* If modem is found then it sets modem_dev to device structure
     for modem, and modem =1 */
  if ( !find_modem() ) {
    printf ("Sorry, no Lucent PCI modem that I know of was found.\n");
    printf ("If you have one fitted then please mail me with the details\n");
    printf ("at: richard@@close.u-net.com please include an output from\n");
    printf ("cat /proc/pci and as much info. on the card as possible.\n");
    printf ("If you have an ISA modem please see README.ISA.\n");
    exit(1);
  }

  while ((c = getopt(argc, argv, "zimovthpd:uc" )) != -1) {
    switch(c) {
    case 'z':
      show_modem();
      setup_irq();
	  io_init();
      test_irq();
      break;
    case 'i':
      show_modem();
      main_menu();
      break;
    case 'c':
      command_mode();
      break;
    case 't':
      show_modem();
      setup_irq();
      io_init();
      hangup();
      break;
    case 'u':	/* Full duplex transmit/receive */
      //      show_modem();
      setup_irq();
      io_init();
      voice_init();
      dp_offhook_cmd();
      voice_transmit(-1);
      die( "Should be unreachable\n" ); // ???
      break;
    case 'd':
      show_modem();
      setup_irq();
      io_init();
	  dp_update_modem_options();

      setSpeaker(true, 3);

	  { unsigned short my_timer;
      my_timer = x_current_time();
      dp_offhook_cmd();
      printf ("dp_offhook_cmd took %dmS.\n", x_elapsed_time(my_timer));
	  }
#if 1
      // What the hell!
	  dp_download_tad();
      // Wait for dial tone.
      printf( "Waiting for dialtone... ");
	  if (waitForDialTone())
		printf("got it!\n");
	  else {
		printf("no dial tone detected, is the phone plugged in?\n");
        hangup();
		break;
	  }
#endif

      // Dial how you want.
      printf( "About to dial %s: ...", optarg );// sleep(3);
      dial(optarg);
      printf( " done.\n");
      sleep(1); // wait for dial to finish!
	
#if WAIT_FOR_ANSWER  

      // Wait for answer tone.
      printf( "Waiting for answer... ");
	  if (waitForAnswerTone())
	    printf("answer tone detected!\n");
	  else
		printf("no answer tone detected, bummer!\n");

#endif
	  
	  // Delay before hanging up, make this long enough to hear
	  // any response from line when messing around with dialling.
	  sleep(5);

      printf( "About to hangup\n" );
      hangup();
      break;

    case 'o':
      show_modem();
      setup_irq();
      io_init();
      big_init();
      voice_init();
      printf("Ready\n" );
      dp_offhook_cmd();
      dp_pulse_dial_cmd(3);	/* How do you prove that number PI does not exist? */
      dp_pulse_dial_cmd(1);	/* You take telephone and dial 3 1 4 1 5 9 2 6 5 4 */
      dp_pulse_dial_cmd(4);	/* and then you hear ta da da called number does */
      dp_pulse_dial_cmd(1);	/* not exist. (It works in Prague at least :-) */
      dp_pulse_dial_cmd(5);
      dp_pulse_dial_cmd(9);
      dp_pulse_dial_cmd(2);
      dp_pulse_dial_cmd(6);
      dp_pulse_dial_cmd(5);
      dp_pulse_dial_cmd(4);
      dp_DTMF_dial_cmd(1);
#if 0
      sleep(1);
      dp_synth_ring_init();
      sleep(1);
      dp_synth_ring_on();
      sleep(1);
      dp_synth_ring_off();
#endif
      sleep(1);

#if 1
      printf( "Staring tad\n" );
      dp_start_tad(0xf0);
      expect_irqs();
#endif

#if 0
      printf( "X_output(13)\n" );
      x_output(0x13);
      expect_irqs();
      x_output(0x1a);
      printf( "Should be ready?\n" );
#endif
      expect_irqs();
      printf( "Should dial 2\n" );
      dp_DTMF_dial_cmd(2);
      expect_irqs();
#if 0
      printf( "Really should dial 2\n" );
      dp_offhook_cmd();
      dial("2");
      expect_irqs();
#endif
#if 0
      expect_irqs();
      printf( "init hdsp\n" );
      dp_init_hdsp();
      expect_irqs();
      printf( "Starting speakerphone\n" );
      dp_start_hdsp();
      expect_irqs();
      printf( "Switching fdsp\n" );
      dp_switch_fdsp();
      expect_irqs();
      {
	  int i = 0;
	  for (i = 0; i<5; i++) {
	    dp_mute_fdsp(1);
	    sleep(1);
	    dp_mute_fdsp(0);
	    sleep(1);
	  }
      }
      printf( "Stop fdsp:\n" );
      dp_stop_fdsp();
      sleep(3);
      printf( "About to hangup.\n" );
      dp_onhook_cmd();
      /* go_offhook(); -- seems to do something slightly different */
      /* dp_download_fax(); */
#endif
      break;
    case 'm':
      continous_monitoring(3, 1000);
      break;
    case 'p':
      pulseDial = true;
      break;
    case 'v':
      verbose++;
      break;
    case 'h':
    default:
      printf( "Usage: ltmodem [-imovthpd]\n" );
      printf( "-i interative use.\n-m monitoring ports/registers.\n");
      printf( "-o prove PI does not exist and turn modem into microwave owen.\n");
      /* -o is really meant for debugging only, and it does strange
         things. Not a toy for people who read help. It does different
         things in every release. */
      printf( "-v increase level of verbosity.\n");
      printf( "-t basic test, display checksum etc. then hangup.\n");
      printf( "-c enter command mode, read commands from fd#3.\n");
      printf( "-u put phone offhook, then start transmitting data from stdin\n"
	      "   and receive data from modem to stdout. You _must_ provide data on stdin\n" );
      printf( "-p enable Pulse dialling, default is Tone.\n");
      printf( "-d dial the specified number.\n");
      printf( "-h print this message!\n");
      goto exit;
    }
  }
  exit:

#if LT_ISAPNP
  cleanup_isa();
#else
  cleanup_pci();
#endif
  return 0;
}

void command_mode(void)
{
  char buf[10240];
  FILE *cmd = fdopen(3, "r");

  fprintf(stderr, "PROTOCOL 0.0\n" );
  fprintf(stderr, "SWVERSION ltmodem " LTMODEM_VERSION "\n" );
  //  show_modem();
  setup_irq();
  io_init();
  big_init();
  voice_init();

  fprintf(stderr, "HWVERSION mars V%x.%x (rom checksum %x)\n", x_chip_version, dp_version, rom_checksum );
  fprintf(stderr, "+ Command mode ready\n" );

  while (fgets(buf, 10235, cmd) != NULL) {
    //    fprintf(stderr, "# Got command %s\n", buf );

    if (!strncmp(buf, "onhook", 6)) {
      dp_onhook_cmd();
      fprintf(stderr, "+ OK\n" );
    } else if (!strncmp(buf, "offhook", 7)) {
      dp_offhook_cmd();
      fprintf(stderr, "+ OK\n" );
    } else if (!strncmp(buf, "duplex", 6)) {
      voice_transmit(3);
    } else if (!strncmp(buf, "quit", 4)) {
      fprintf(stderr, "+ exiting\n" );
      exit(0);
    } else
      fprintf(stderr, "- unknown command %s\n", buf );
  }

  PRINTF( "# Exiting command mode\n" );
  exit(1);
}


void setup_irq(void)
{
  // Setup IRQ variable used by other stuff.
  modem_irq = get_modem_irq();
}

// Modem monitoring functions.
void
monitor_modem(void)
{
  // Value input by user.
  char input = 'z';

  // Monitoring activity type:
  // registers = 1, I/O = 2.
  int monitor_type = 1;

  // Monitoring period in milliseconds, defaults to one second.
  int monitoring_interval = 1000;

  while (input != 'Q') {
	// Ignore the newline char.
	if (input != '\n') {
	  printf ("***************************************************\n");
      printf ("monitoring menu (Monitor monitorIo monitorRegs monitorBoth iNterval Quit): ");

	}
	// Get user input in uppercase.
	input = toupper (getchar());
    switch (input) {
	case 'M':
	  continous_monitoring(monitor_type, monitoring_interval);
	  break;
	case 'I':
      printf( "Will monitor I/O ports.\n" );
      monitor_type = 2;
      break;
    case 'R':
      printf( "Will monitor PCI registers.\n" );
      monitor_type = 1;
      break;
    case 'B':
      printf( "Will monitor I/O ports and PCI registers.\n" );
      monitor_type = 3;
      break;
    case 'N':
      monitoring_interval = set_monitoring_interval();
      break;
	case '\n':
      break;
	case 'Q':
	  break;
	default:
	  printf ("Illegal option: %c\n", input);
	}    
  }
}

int set_monitoring_interval(void){

  // Value input by user.
  int input = 0;
  char trash; 

  // Allow user to set interval.
  printf ("Set monitoring interval (in miliseconds): ");
  scanf ("%d%c", &input, &trash);

  if (input > 0) {
	// Return the user's value.
	printf ("Interval set to %d milliseconds.\n", input); 
	return input;
  }
  else {
	// Default to one second.
	printf ("Illegal interval, using 1 second default.\n"); 
	return 1000;
  }
}

/* Modem writing functions. */
void
set_modem(void)
{
  /* value input by user. */
  char input = ' ';

  /* start by just doing a hex dump. */
#if LT_ISAPNP
  show_hex_dump();
#else
  show_hex_dump(modem_dev);
#endif

  /* Offer the user a choice of what to set. */
  while (input != 'Q') {

	// Ignore newline character.
	if (input != '\n') {
       printf ("modem write (Controlreg Io Quit): ");
	}
	input = toupper (getchar ());
    switch (input) {
	case 'C':
#if LT_ISAPNP
          printf ("Option not valid for ISA modems.");
#else
	  set_modem_cont_reg();
	  redisplay_modem_regs();
#endif
	  break;
	case 'I':
	  set_modem_io();
	  break;
	case '\n':
      break;
	case 'Q':
	  break;
	default:
	  printf ("Illegal option: %c\n", input);
	}   
  }
}
/* Main command menu. */

void
main_menu(void)
{
  /* char input by user. */
  char input = 'z';

  while (input != 'Q') {
	// Ignore the newline char.
	if (input != '\n') {
      printf ("main menu (Monitor Write Quit): ");
	}
	// Get user input in uppercase.
	input = toupper (getchar());
    switch (input) {
	case 'M':
	  monitor_modem();
	  break;
	case 'W':
	  set_modem();
	  break;
	case '\n':
      break;
	case 'Q':
	  break;
	default:
	  printf ("Illegal option: %c\n", input);
	}    

  }
  /* Bye bye... */
  printf ("User stopped ltmodem.\n");
}

// Lucent modem specific stuff.  

void go_onhook(void)
{
  dp_onhook_cmd();
}

void io_init(void)
{

   // Set up the port IO.
   port_io_init(io_address[1], io_address[2]);

   // Set up EEPROM ?
   //SetUpEEPROM();

   // Set up the modem variables etc.
   MimicInit();

}

// Dial the number held in the argument string.
void dial(char *s)
{
  sleep(2);	/* We do no dial tone detection, so we'll just wait */
  while (*s) {

	//printf( "Dialing: `%c'.\n", *s );

    switch (*s) {
    case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
	  // Delay before each one.
	  usleep(400000);
      if (pulseDial) {
		usleep(50000 * (*s));
		dp_pulse_dial_cmd(*s-'0');
	  }
	  else 
		dp_DTMF_dial_cmd(*s-'0');
	  break;

    default:
      printf( "Unknown character in dial sequence `%c' ignored.\n", *s );
      break;
    }
    s++;
  }
}

// Mess around with speaker.
void setSpeaker (bool Enabled, unsigned char Volume)
{

  // Set speaker globals.
  S_speaker_enable = (unsigned char)Enabled;
  S_speaker_volume = Volume; 

  dp_56k_speaker_cmd ();

}

// Wait for dial tone, timing out after 3 seconds.
bool waitForDialTone (void)
{

  int timeout = 3000;
  short local_timer;

  local_timer = x_current_time();

  // Set up tone detection.
  dp_detect_tones_cmd();

  // Wait until dial tone detected or 3 seconds has expired.
  while (!dp_dial_tone_detected()) {
	if (x_elapsed_time(local_timer) > timeout)
	  return false;
	usleep(1000);
  }
  return true;
}

// Wait for answer tone, timing out after 10 seconds.
bool waitForAnswerTone (void)
{

  int timeout = 10000;
  unsigned short local_timer;

  dp_answer_state = 0;

  local_timer = x_current_time();

  // Set up tone detection.
  dp_detect_tones_cmd();

  // Wait until answer tone detected or 10 seconds has expired.
  while (!dp_answer_tone_detected()) {
	if (x_elapsed_time(local_timer) > timeout)
	  return false;
        if (dp_busy_tone_detected()) {
	  printf("The line is busy!\n");
          return false;
	}
  }
  return true;
}

void hangup (void)
{
  // This is the same as a case clause in dp_period_task.
  dp_onhook_cmd();
  _S[0x74] = 0;
  dp_state = 1;
  x_modem_state = 1;
  dp_timer = x_current_time();

  // This is what Pavel had put at the end of dp_onhook_cmd.
  printf( "This should really hangup: " );
  modem_reset(); 
  printf( "\n" );
}



@1.6log@Updated for 0.9.2 catchup build.@text@d2 1a2 1 *	$Id: ltmodem.c,v 1.5 1999/08/22 03:35:38 root Exp root $
d4 1a4 1 *	Lucent PCI modem diagnostics tool.
a14 3#define TRY_INTERRUPTS 0
#define WAIT_FOR_ANSWER 1  

d29 3d33 1d42 1a42 1    printf ("I'm sorry but ISA cards are *NOT* supported.\n");
d46 1a46 1  while ((c = getopt(argc, argv, "imovthpd:uc" )) != -1) {
d48 6d65 1a65 1      big_init();
a70 1      big_init();
d80 1a80 1      big_init();
d83 3

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -