📄 clm_modem.c
字号:
/* * CLModem v0.3.0 - High level modem routines * * Copyright (C) 2000 Mikhail Moreyra * * This file may be redistributed under the terms of the GNU Public * License. */#define __NO_VERSION__#include <linux/kernel.h>#include <linux/module.h>#include <linux/wrapper.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/ctype.h>#include "clm_config.h"#include "clm_dspdrv.h"#include "clm_modem.h"void init_modem_task(void);void end_modem_task(void);struct timer_list mtimer;int last_cp, last_ms;volatile int modem_has_connected = 0;extern struct tty_struct *clm_tty;const char *modem_modes_tbl[] = { NULL, NULL, "V.21", NULL, "V.23 A", "V.23 B", "V.22", "V.22Bis", NULL, NULL, NULL, NULL, "V.32", "V.32 QAM", NULL, NULL, "V.32Bis", "V.34 Symm", "V.34 Asym", NULL, NULL, NULL, "X2", "V.90"};const int modem_rates_tbl[] = { 0, 0, 300, 1200, 2400, 4800, 7200, 9600, 12000, 14400, 16800, 19200, 0, 0, 0, 0, 21600, 24000, 26400, 28800, 31200, 33600};intinit_modem(void){ char x; Msg("CLM: Initializing modem...\n"); ResetDspInternal(); dspdrv_clear_dsp_interrupt(); ResetDspPoweron(); ResetDspIdle (); dspdrv_ReadCram(0xfc, &x, 1); x &= 0xbf; dspdrv_WriteCram(0xfc, &x, 1); Dbg("Initializing Call Progress 0 (CP_INIT)\n"); init_call_progress (CP_INIT); last_ms = read_dsp_modem_status_reg() & 0xf; last_cp = call_progress(); modem_has_connected = 0; line_init(); return 0;}voidreset_modem(void){ Msg("CLM: Reseting modem...\n"); modem_has_connected = 0; ResetDspIdle(); init_call_progress (CP_INIT); ResetDspInternal(); dspdrv_clear_dsp_interrupt();}intwait_for_dialtone(void){ int i, cp; int dialtone = 0; Dbg("Initializing Call Progress 1 (WAIT_FOR_DIALTONE)\n"); init_call_progress(CP_WAIT_FOR_DIALTONE); delay(2000); for (i=0; i<WAIT_FOR_DIALTONE_TIME*10; i++) { cp = call_progress(); if (cp != last_cp) { last_cp = cp; if (cp == C_DIALTONE_DETECTED) { dialtone = 1; Msg("DIALTONE Detected!\n"); break; } else if (cp == C_NO_DIALTONE) /* Just Wait */ ; else Msg("UNKNOWN Call Progress: %d\n", cp); } delay(100); /* 0.1 secs */ } if (cp == C_NO_DIALTONE) Msg("NO DIALTONE\n"); return dialtone;}voiddial_number(int dialing_type, char *phone){ int dial_time, pdt; if (toupper(*phone) == 'P') { dialing_type = PULSE_DIALING; phone++; } else if (toupper(*phone) == 'T') { dialing_type = TONE_DIALING; phone++; } if (dialing_type == PULSE_DIALING) modem_config_dial(PULSE_MAKE_TIME, PULSE_BREAK_TIME, PULSE_DIALING, 0x2ee); else { /* TONE_DIALING */ ModemSetTxLevel(TL_TONE); modem_config_dial(DTMF_DIALING_SPEED, DTMF_DIALING_SPEED, TONE_DIALING, 0); } while (*phone) { if ( ((*phone >= '0') && (*phone <= '9')) || ( (dialing_type == TONE_DIALING) && ( ((*phone >= 'A') && (*phone <= 'D')) || (*phone == '#') || (*phone == '*') ) ) ) { Msg("Dialing %c...\n", *phone); if (dialing_type == PULSE_DIALING) { pdt = *phone - '0'; if (pdt == 0) pdt = 10; dial_time = (PULSE_MAKE_TIME + PULSE_BREAK_TIME)*pdt + 0x2ee; } else { /* TONE_DIALING */ dial_time = 2*DTMF_DIALING_SPEED; } modem_dial_digit(*phone); delay(dial_time); } else Msg("Dialing Error\n"); phone++; }}voidconnection_init(void){ /* mt_v8_configure */ ConfigPatch(5); DspPatch(TRAINING_PATCH); ConfigPatch(0); /* mt_v8_configure */}intwait_for_answer(void){ int i, cp; int remote_answer = 0; Dbg("Initializing Call Progress 2 (CP_WAIT_FOR_ANSWER)\n"); init_call_progress (CP_WAIT_FOR_ANSWER); for (i=0; i<WAIT_FOR_ANSWER_TIME*10; i++) { cp = call_progress(); if (cp != last_cp) { last_cp = cp; if (cp == C_ANSWER_DETECTED) { remote_answer = 1; Msg("Remote MODEM Answered!\n"); break; } else if (cp == C_BUSY_DETECTED) { Msg("BUSY\n"); break; } else if ((cp == 0)|| (cp == 4)) /* Nothing */ ; else Msg("UNKNOWN Call Progress: %d\n", cp); } delay(100); /* 0.1 secs */ } return remote_answer;}intwait_for_carrier(void){ int i, cp, modem_status; char modem_mode, modem_baudtx, modem_baudrx; int carrier_detected = 0; for (i=0; i<WAIT_FOR_CARRIER_TIME*10; i++) { /* Doesn't count v8_orig() */ cp = call_progress(); if (cp != last_cp) Dbg("New Call Progress : %x\n", last_cp = cp); modem_status = read_dsp_modem_status_reg() & 0xf; if (modem_status != last_ms) { last_ms = modem_status; if (modem_status == M_HANDSHAKING) { Msg("MODEM is Handshaking...\n");#ifdef V34 if (v8_orig(BR_33600) == -1) { Msg("Couldn't establish V.34 connection\n"); break; } last_cp = call_progress();#endif } else if (modem_status == M_CONNECTED) { carrier_detected = 1; Msg("MODEM Has Connected!\n"); DspPatch(DATA_PATCH); ConfigPatch(2); set_speaker(SPKR_OFF); break; } else Msg("Unknown Modem Status: %#x\n", modem_status); } delay(100); /* 0.1 secs */ } if (carrier_detected) { modem_mode = get_receiver_mode(); Msg("Modem Mode: %s\n", modem_modes_tbl[(int)modem_mode]); mt_get_receiver_speed(&modem_baudtx, &modem_baudrx); Msg("Modem Baud TX: %d\n", modem_rates_tbl[(int)modem_baudtx]); Msg("Modem Baud RX: %d\n", modem_rates_tbl[(int)modem_baudrx]); line_init(); line_port_init(0); /* ? */ line_disable_interrupts(); line_io_enable(1); dspdrv_ping_cram_intr(); modem_has_connected = 1; line_enable_interrupts(); init_modem_task(); } else Msg("NO CARRIER\n"); /* Dbg("CLM_STATUS: txc: %d -- rxc: %d\n", tx_count(), rx_count()); */ return carrier_detected;}intorig_modem_connection(void){ connection_init(); /* update_modem_rate_seq */#ifdef V34 /* MIN Baud rate = 300 */ /* MAX Baud rate = 28800 */ /* mt_set_rate_seq(0xfff, 0xfff, 0); */ /* MAX Baud rate = 33600 */ mt_set_rate_seq(0x3fff, 0x3fff, 0);#else /* MIN Baud rate = 300 */ /* MAX Baud rate = 14400 */ mt_set_rate_seq(0x3f, 0x3f, 0);#endif ModemSetTxLevel(TL_DATA); if (wait_for_answer() == 1) {#ifdef V34 Msg("Connecting V.34 at 33600 bps...\n"); mt_connect(M_CONN_ORIG, BR_14400, MD_V34, 0, 0, 3, 0, 1, 0);#else Msg("Connecting V.32bis at 14400 bps...\n"); mt_connect(M_CONN_ORIG, BR_14400, MD_V32BIS, 0, 0, 1, 0, 1, 0);#endif if(wait_for_carrier()) return 1; else return 0; } else { Msg("NO ANSWER"); return 0; }}voidend_connection(void){ modem_has_connected = 0; line_io_enable(0); end_modem_task(); Msg("CLM: Connection Terminated.\n");}voidmodem_task(unsigned long x){ int cp, modem_status; int hangup = 0; cp = call_progress(); if (cp != last_cp) Msg("New Call Progress : %x\n", last_cp = cp); modem_status = read_dsp_modem_status_reg() & 0xf; if (modem_status != last_ms) { last_ms = modem_status; if (modem_status == M_DROP) { Msg("Remote Modem hangup.\n"); hangup = 1; } else if (modem_status == M_RETRAINING_X) { Msg("Modem Retraining???\n"); } else if (modem_status == M_RETRAINING) { Msg("Modem is Retraining\n"); hangup = 1; } else Msg("New Modem Status: %#x\n", modem_status); } if (hangup) { Dbg("Hanging up Terminal.\n"); tty_hangup(clm_tty); } else init_modem_task();}voidinit_modem_task(void){ init_timer(&mtimer); mtimer.expires = jiffies + 10; /* 100 ms */ mtimer.data = 0; mtimer.function = modem_task; add_timer(&mtimer);}voidend_modem_task(void){ del_timer(&mtimer);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -