patch-2.3.14 linux/drivers/isdn/isdn_tty.c
Next file: linux/drivers/isdn/isdn_tty.h
Previous file: linux/drivers/isdn/isdn_ppp.h
Back to the patch index
Back to the overall index
- Lines: 995
- Date:
Thu Aug 12 09:42:33 1999
- Orig file:
v2.3.13/linux/drivers/isdn/isdn_tty.c
- Orig date:
Sun May 23 10:03:42 1999
diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.c,v 1.63 1999/04/12 12:33:39 fritz Exp $
+/* $Id: isdn_tty.c,v 1.72 1999/07/31 12:59:45 armin Exp $
* Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
*
@@ -20,6 +20,43 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_tty.c,v $
+ * Revision 1.72 1999/07/31 12:59:45 armin
+ * Added tty fax capabilities.
+ *
+ * Revision 1.71 1999/07/27 10:34:34 armin
+ * Fixed last change. Did not compile with AUDIO support off.
+ *
+ * Revision 1.70 1999/07/25 16:17:58 keil
+ * Fix Suspend/Resume
+ *
+ * Revision 1.69 1999/07/25 12:56:15 armin
+ * isdn_tty_at_cout() now queues the message if online and
+ * data is in queue or flip buffer is full.
+ * needed for fax connections.
+ *
+ * Revision 1.68 1999/07/11 17:51:51 armin
+ * Bugfix, "-" was missing for AT&L settings.
+ *
+ * Revision 1.67 1999/07/11 17:14:12 armin
+ * Added new layer 2 and 3 protocols for Fax and DSP functions.
+ * Moved "Add CPN to RING message" to new register S23,
+ * "Display message" is now correct on register S13 bit 7.
+ * New audio command AT+VDD implemented (deactivate DTMF decoder and
+ * activate possible existing hardware/DSP decoder).
+ * Moved some tty defines to .h file.
+ * Made whitespace possible in AT command line.
+ * Some AT-emulator output bugfixes.
+ * First Fax G3 implementations.
+ *
+ * Revision 1.66 1999/07/07 10:13:46 detabc
+ * remove unused messages
+ *
+ * Revision 1.65 1999/07/04 21:01:59 werner
+ * Added support for keypad and display (ported from 2.0)
+ *
+ * Revision 1.64 1999/07/01 08:30:00 keil
+ * compatibility to 2.3 kernel
+ *
* Revision 1.63 1999/04/12 12:33:39 fritz
* Changes from 2.0 tree.
*
@@ -61,24 +98,12 @@
* brute force fix to avoid Ugh's in isdn_tty_write()
* cleaned up some dead code
*
- * Revision 1.54 1998/06/07 00:20:13 fritz
- * abc cleanup.
*
- * Revision 1.53 1998/06/02 12:10:16 detabc
- * wegen einer einstweiliger verfuegung gegen DW ist zur zeit
- * die abc-extension bis zur klaerung der rechtslage nicht verfuegbar
*
* Revision 1.52 1998/03/19 13:18:21 keil
* Start of a CAPI like interface for supplementary Service
* first service: SUSPEND
*
- * Revision 1.51 1998/03/08 14:26:11 detabc
- * change kfree_skb to dev_kfree_skb
- * remove SET_SKB_FREE
- *
- * Revision 1.50 1998/03/08 13:14:28 detabc
- * abc-extension support for kernels > 2.1.x
- * first try (sorry experimental)
*
* Revision 1.49 1998/03/08 00:01:59 fritz
* Bugfix: Lowlevel module usage and channel usage were not
@@ -303,7 +328,6 @@
static void isdn_tty_check_esc(const u_char *, u_char, int, int *, int *, int);
static void isdn_tty_modem_reset_regs(modem_info *, int);
static void isdn_tty_cmd_ATA(modem_info *);
-static void isdn_tty_at_cout(char *, modem_info *);
static void isdn_tty_flush_buffer(struct tty_struct *);
static void isdn_tty_modem_result(int, modem_info *);
#ifdef CONFIG_ISDN_AUDIO
@@ -321,64 +345,8 @@
static int si2bit[8] =
{4, 1, 4, 4, 4, 4, 4, 4};
-char *isdn_tty_revision = "$Revision: 1.63 $";
+char *isdn_tty_revision = "$Revision: 1.72 $";
-#define DLE 0x10
-#define ETX 0x03
-#define DC4 0x14
-
-/*
- * Definition of some special Registers of AT-Emulator
- */
-#define REG_RINGATA 0
-#define REG_RINGCNT 1
-#define REG_ESC 2
-#define REG_CR 3
-#define REG_LF 4
-#define REG_BS 5
-
-#define REG_WAITC 7
-
-#define REG_RESP 12
-#define BIT_RESP 1
-#define REG_RESPNUM 12
-#define BIT_RESPNUM 2
-#define REG_ECHO 12
-#define BIT_ECHO 4
-#define REG_DCD 12
-#define BIT_DCD 8
-#define REG_CTS 12
-#define BIT_CTS 16
-#define REG_DTRR 12
-#define BIT_DTRR 32
-#define REG_DSR 12
-#define BIT_DSR 64
-#define REG_CPPP 12
-#define BIT_CPPP 128
-
-#define REG_T70 13
-#define BIT_T70 2
-#define BIT_T70_EXT 32
-#define REG_DTRHUP 13
-#define BIT_DTRHUP 4
-#define REG_RESPXT 13
-#define BIT_RESPXT 8
-#define REG_CIDONCE 13
-#define BIT_CIDONCE 16
-#define REG_RUNG 13
-#define BIT_RUNG 64
-#define REG_RESRXT 13
-#define BIT_RESRXT 128
-
-#define REG_L2PROT 14
-#define REG_L3PROT 15
-#define REG_PSIZE 16
-#define REG_WSIZE 17
-#define REG_SI1 18
-#define REG_SI2 19
-#define REG_SI1I 20
-#define REG_PLAN 21
-#define REG_SCREEN 22
/* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
* to stuff incoming data directly into a tty's flip-buffer. This
@@ -514,7 +482,7 @@
#ifdef CONFIG_ISDN_AUDIO
ifmt = 1;
- if (info->vonline)
+ if ((info->vonline) && (!info->emu.vpar[4]))
isdn_audio_calc_dtmf(info, skb->data, skb->len, ifmt);
if ((info->vonline & 1) && (info->emu.vpar[1]))
isdn_audio_calc_silence(info, skb->data, skb->len, ifmt);
@@ -580,6 +548,15 @@
ISDN_AUDIO_SKB_DLECOUNT(skb) =
isdn_tty_countDLE(skb->data, skb->len);
}
+#ifdef CONFIG_ISDN_TTY_FAX
+ else {
+ if (info->faxonline & 2) {
+ isdn_tty_fax_bitorder(info, skb);
+ ISDN_AUDIO_SKB_DLECOUNT(skb) =
+ isdn_tty_countDLE(skb->data, skb->len);
+ }
+ }
+#endif
#endif
/* Try to deliver directly via tty-flip-buf if queue is empty */
save_flags(flags);
@@ -909,6 +886,35 @@
}
}
+/*
+ * return the usage calculated by si and layer 2 protocol
+ */
+int
+isdn_calc_usage(int si, int l2)
+{
+ int usg = ISDN_USAGE_MODEM;
+
+#ifdef CONFIG_ISDN_AUDIO
+ if (si == 1) {
+ switch(l2) {
+ case ISDN_PROTO_L2_MODEM:
+ usg = ISDN_USAGE_MODEM;
+ break;
+#ifdef CONFIG_ISDN_TTY_FAX
+ case ISDN_PROTO_L2_FAX:
+ usg = ISDN_USAGE_FAX;
+ break;
+#endif
+ case ISDN_PROTO_L2_TRANS:
+ default:
+ usg = ISDN_USAGE_VOICE;
+ break;
+ }
+ }
+#endif
+ return(usg);
+}
+
/* isdn_tty_dial() performs dialing of a tty an the necessary
* setup of the lower levels before that.
*/
@@ -928,8 +934,14 @@
si = bit2si[j];
break;
}
+ usg = isdn_calc_usage(si, l2);
#ifdef CONFIG_ISDN_AUDIO
- if ((si == 1) && (l2 != ISDN_PROTO_L2_MODEM)) {
+ if ((si == 1) &&
+ (l2 != ISDN_PROTO_L2_MODEM)
+#ifdef CONFIG_ISDN_TTY_FAX
+ && (l2 != ISDN_PROTO_L2_FAX)
+#endif
+ ) {
l2 = ISDN_PROTO_L2_TRANS;
usg = ISDN_USAGE_VOICE;
}
@@ -967,6 +979,12 @@
cmd.driver = info->isdn_driver;
cmd.command = ISDN_CMD_SETL3;
cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
+#ifdef CONFIG_ISDN_TTY_FAX
+ if (l2 == ISDN_PROTO_L2_FAX) {
+ cmd.parm.fax = info->fax;
+ info->fax->direction = ISDN_TTY_FAX_CONN_OUT;
+ }
+#endif
isdn_command(&cmd);
cmd.driver = info->isdn_driver;
cmd.arg = info->isdn_channel;
@@ -989,7 +1007,7 @@
* ISDN-line (hangup). The usage-status is cleared
* and some cleanup is done also.
*/
-static void
+void
isdn_tty_modem_hup(modem_info * info, int local)
{
isdn_ctrl cmd;
@@ -1010,6 +1028,12 @@
}
#ifdef CONFIG_ISDN_AUDIO
info->vonline = 0;
+#ifdef CONFIG_ISDN_TTY_FAX
+ info->faxonline = 0;
+ info->fax->phase = ISDN_FAX_PHASE_IDLE;
+#endif
+ info->emu.vpar[4] = 0;
+ info->emu.vpar[5] = 8;
if (info->dtmf_state) {
kfree(info->dtmf_state);
info->dtmf_state = NULL;
@@ -1041,9 +1065,8 @@
}
isdn_all_eaz(info->isdn_driver, info->isdn_channel);
info->emu.mdmreg[REG_RINGCNT] = 0;
- usage = ((info->emu.mdmreg[REG_SI1I] != 1) ||
- (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM)) ?
- ISDN_USAGE_MODEM : ISDN_USAGE_VOICE;
+ usage = isdn_calc_usage(info->emu.mdmreg[REG_SI1I],
+ info->emu.mdmreg[REG_L2PROT]);
isdn_free_channel(info->isdn_driver, info->isdn_channel,
usage);
}
@@ -1130,8 +1153,14 @@
si = bit2si[j];
break;
}
+ usg = isdn_calc_usage(si, l2);
#ifdef CONFIG_ISDN_AUDIO
- if ((si == 1) && (l2 != ISDN_PROTO_L2_MODEM)) {
+ if ((si == 1) &&
+ (l2 != ISDN_PROTO_L2_MODEM)
+#ifdef CONFIG_ISDN_TTY_FAX
+ && (l2 != ISDN_PROTO_L2_FAX)
+#endif
+ ) {
l2 = ISDN_PROTO_L2_TRANS;
usg = ISDN_USAGE_VOICE;
}
@@ -1184,11 +1213,11 @@
cmd.parm.cmsg.para[5] = l;
strncpy(&cmd.parm.cmsg.para[6], id, l);
cmd.command =CAPI_PUT_MESSAGE;
-/* info->dialing = 1;
- strcpy(dev->num[i], n);
+ info->dialing = 1;
+// strcpy(dev->num[i], n);
isdn_info_update();
-*/
isdn_command(&cmd);
+ isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
}
}
@@ -1218,8 +1247,14 @@
si = bit2si[j];
break;
}
+ usg = isdn_calc_usage(si, l2);
#ifdef CONFIG_ISDN_AUDIO
- if ((si == 1) && (l2 != ISDN_PROTO_L2_MODEM)) {
+ if ((si == 1) &&
+ (l2 != ISDN_PROTO_L2_MODEM)
+#ifdef CONFIG_ISDN_TTY_FAX
+ && (l2 != ISDN_PROTO_L2_FAX)
+#endif
+ ) {
l2 = ISDN_PROTO_L2_TRANS;
usg = ISDN_USAGE_VOICE;
}
@@ -1863,11 +1898,11 @@
static int
isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info * info)
{
-#if LINUX_VERSION_CODE < 131841
+#ifdef COMPAT_HAS_NEW_WAITQ
+ DECLARE_WAITQUEUE(wait, NULL);
+#else
struct wait_queue wait =
{current, NULL};
-#else
- DECLARE_WAITQUEUE(wait, NULL);
#endif
int do_clocal = 0;
unsigned long flags;
@@ -2191,6 +2226,7 @@
m->profile[18] = 4;
m->profile[19] = 0;
m->profile[20] = 0;
+ m->profile[23] = 0;
m->pmsn[0] = '\0';
m->plmsn[0] = '\0';
}
@@ -2203,6 +2239,42 @@
m->vpar[1] = 0; /* Silence detection level (0 = none ) */
m->vpar[2] = 70; /* Silence interval (7 sec. ) */
m->vpar[3] = 2; /* Compression type (1 = ADPCM-2 ) */
+ m->vpar[4] = 0; /* DTMF detection level (0 = softcode ) */
+ m->vpar[5] = 8; /* DTMF interval (8 * 5 ms. ) */
+}
+#endif
+
+#ifdef CONFIG_ISDN_TTY_FAX
+static void
+isdn_tty_modem_reset_faxpar(modem_info * info)
+{
+ T30_s *f = info->fax;
+
+ f->code = 0;
+ f->phase = ISDN_FAX_PHASE_IDLE;
+ f->direction = 0;
+ f->resolution = 1; /* fine */
+ f->rate = 5; /* 14400 bit/s */
+ f->width = 0;
+ f->length = 0;
+ f->compression = 0;
+ f->ecm = 0;
+ f->binary = 0;
+ f->scantime = 0;
+ memset(&f->id[0], 32, FAXIDLEN - 1);
+ f->id[FAXIDLEN - 1] = 0;
+ f->badlin = 0;
+ f->badmul = 0;
+ f->bor = 0;
+ f->nbc = 0;
+ f->cq = 0;
+ f->cr = 0;
+ f->ctcrty = 0;
+ f->minsp = 0;
+ f->phcto = 30;
+ f->rel = 0;
+ memset(&f->pollid[0], 32, FAXIDLEN - 1);
+ f->pollid[FAXIDLEN - 1] = 0;
}
#endif
@@ -2219,6 +2291,9 @@
#ifdef CONFIG_ISDN_AUDIO
isdn_tty_modem_reset_vpar(m);
#endif
+#ifdef CONFIG_ISDN_TTY_FAX
+ isdn_tty_modem_reset_faxpar(info);
+#endif
m->mdmcmdl = 0;
}
@@ -2291,10 +2366,16 @@
}
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
info = &m->info[i];
-#if LINUX_VERSION_CODE < 131841
- info->write_sem = MUTEX;
-#else
+#ifdef CONFIG_ISDN_TTY_FAX
+ if (!(info->fax = kmalloc(sizeof(T30_s), GFP_KERNEL))) {
+ printk(KERN_ERR "Could not allocate fax t30-buffer\n");
+ return -3;
+ }
+#endif
+#ifdef COMPAT_HAS_NEW_WAITQ
init_MUTEX(&info->write_sem);
+#else
+ info->write_sem = MUTEX;
#endif
sprintf(info->last_cause, "0000");
sprintf(info->last_num, "none");
@@ -2312,14 +2393,14 @@
info->blocked_open = 0;
info->callout_termios = m->cua_modem.init_termios;
info->normal_termios = m->tty_modem.init_termios;
-#if LINUX_VERSION_CODE < 131841
- info->open_wait = 0;
- info->close_wait = 0;
-#else
+#ifdef COMPAT_HAS_NEW_WAITQ
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
-#endif
+#else
+ info->open_wait = 0;
+ info->close_wait = 0;
info->isdn_driver = -1;
+#endif
info->isdn_channel = -1;
info->drv_index = -1;
info->xmit_size = ISDN_SERIAL_XMIT_SIZE;
@@ -2371,8 +2452,15 @@
break;
}
return ret;
- } else
- return isdn_wildmat(cid, isdn_map_eaz2msn(emu->msn, di));
+ } else {
+ int tmp;
+ tmp = isdn_wildmat(cid, isdn_map_eaz2msn(emu->msn, di));
+#ifdef ISDN_DEBUG_MODEM_ICALL
+ printk(KERN_DEBUG "m_fi: mmsn=%s -> tmp=%d\n",
+ isdn_map_eaz2msn(emu->msn, di), tmp);
+#endif
+ return tmp;
+ }
}
/*
@@ -2424,7 +2512,7 @@
(info->emu.mdmreg[REG_SI2] == si2)) { /* SI2 is matching */
idx = isdn_dc2minor(di, ch);
#ifdef ISDN_DEBUG_MODEM_ICALL
- printk(KERN_DEBUG "m_fi: match1\n");
+ printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret);
printk(KERN_DEBUG "m_fi: idx=%d flags=%08lx drv=%d ch=%d usg=%d\n", idx,
info->flags, info->isdn_driver, info->isdn_channel,
dev->usage[idx]);
@@ -2446,8 +2534,7 @@
info->drv_index = idx;
dev->m_idx[idx] = info->line;
dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
- dev->usage[idx] |= ((si1 != 1) || (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM)) ?
- ISDN_USAGE_MODEM : ISDN_USAGE_VOICE;
+ dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]);
strcpy(dev->num[idx], nr);
strcpy(info->emu.cpn, eaz);
info->emu.mdmreg[REG_SI1I] = si2bit[si1];
@@ -2514,6 +2601,19 @@
/* Signal cause to tty-device */
strncpy(info->last_cause, c->parm.num, 5);
return 1;
+ case ISDN_STAT_DISPLAY:
+#ifdef ISDN_TTY_STAT_DEBUG
+ printk(KERN_DEBUG "tty_STAT_DISPLAY ttyI%d\n", info->line);
+#endif
+ /* Signal display to tty-device */
+ if ((info->emu.mdmreg[REG_DISPLAY] & BIT_DISPLAY) &&
+ !(info->emu.mdmreg[REG_RESPNUM] & BIT_RESPNUM)) {
+ isdn_tty_at_cout("\r\n", info);
+ isdn_tty_at_cout("DISPLAY: ", info);
+ isdn_tty_at_cout(c->parm.display, info);
+ isdn_tty_at_cout("\r\n", info);
+ }
+ return 1;
case ISDN_STAT_DCONN:
#ifdef ISDN_TTY_STAT_DEBUG
printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line);
@@ -2612,6 +2712,27 @@
}
}
return 1;
+#ifdef CONFIG_ISDN_TTY_FAX
+ case ISDN_STAT_FAXIND:
+ if (TTY_IS_ACTIVE(info)) {
+ isdn_tty_fax_command(info);
+ }
+ break;
+#endif
+#ifdef CONFIG_ISDN_AUDIO
+ case ISDN_STAT_AUDIO:
+ if (TTY_IS_ACTIVE(info)) {
+ switch(c->parm.num[0]) {
+ case ISDN_AUDIO_DTMF:
+ if (info->vonline) {
+ isdn_audio_put_dle_code(info,
+ c->parm.num[1]);
+ }
+ break;
+ }
+ }
+ break;
+#endif
}
}
return 0;
@@ -2621,13 +2742,13 @@
Modem-Emulator-Routines
*********************************************************************/
-#define cmdchar(c) ((c>' ')&&(c<=0x7f))
+#define cmdchar(c) ((c>=' ')&&(c<=0x7f))
/*
* Put a message from the AT-emulator into receive-buffer of tty,
* convert CR, LF, and BS to values in modem-registers 3, 4 and 5.
*/
-static void
+void
isdn_tty_at_cout(char *msg, modem_info * info)
{
struct tty_struct *tty;
@@ -2635,6 +2756,8 @@
char *p;
char c;
ulong flags;
+ struct sk_buff *skb = 0;
+ char *sp = 0;
if (!msg) {
printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n");
@@ -2643,6 +2766,34 @@
save_flags(flags);
cli();
tty = info->tty;
+ if ((info->flags & ISDN_ASYNC_CLOSING) || (!tty)) {
+ restore_flags(flags);
+ return;
+ }
+
+ /* use queue instead of direct flip, if online and */
+ /* data is in queue or flip buffer is full */
+ if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) ||
+ (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) {
+ skb = alloc_skb(strlen(msg)
+#ifdef CONFIG_ISDN_AUDIO
+ + sizeof(isdn_audio_skb)
+#endif
+ , GFP_ATOMIC);
+ if (!skb) {
+ restore_flags(flags);
+ return;
+ }
+#ifdef CONFIG_ISDN_AUDIO
+ skb_reserve(skb, sizeof(isdn_audio_skb));
+#endif
+ sp = skb_put(skb, strlen(msg));
+#ifdef CONFIG_ISDN_AUDIO
+ ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
+ ISDN_AUDIO_SKB_LOCK(skb) = 0;
+#endif
+ }
+
for (p = msg; *p; p++) {
switch (*p) {
case '\r':
@@ -2657,16 +2808,26 @@
default:
c = *p;
}
- if ((info->flags & ISDN_ASYNC_CLOSING) || (!tty)) {
- restore_flags(flags);
- return;
+ if (skb) {
+ *sp++ = c;
+ } else {
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+ break;
+ tty_insert_flip_char(tty, c, 0);
}
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- break;
- tty_insert_flip_char(tty, c, 0);
}
- restore_flags(flags);
- queue_task(&tty->flip.tqueue, &tq_timer);
+ if (skb) {
+ __skb_queue_tail(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel], skb);
+ dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len;
+ restore_flags(flags);
+ /* Schedule dequeuing */
+ if ((dev->modempoll) && (info->rcvsched))
+ isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
+
+ } else {
+ restore_flags(flags);
+ queue_task(&tty->flip.tqueue, &tq_timer);
+ }
}
/*
@@ -2847,7 +3008,7 @@
break;
case 2:
/* Append CPN, if enabled */
- if ((m->mdmreg[REG_RESRXT] & BIT_RESRXT)) {
+ if ((m->mdmreg[REG_CPN] & BIT_CPN)) {
sprintf(s, "/%s", m->cpn);
isdn_tty_at_cout(s, info);
}
@@ -2954,8 +3115,9 @@
int limit=39; /* MUST match the size in isdn_tty_parse to avoid
buffer overflow */
- while (strchr("0123456789,#.*WPTS-", *p) && *p && --cnt>0) {
- if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first))
+ while (strchr(" 0123456789,#.*WPTS-", *p) && *p && --cnt>0) {
+ if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) ||
+ (*p == '*') || (*p == '#'))
*q++ = *p;
p++;
if(!--limit)
@@ -3008,6 +3170,9 @@
case ISDN_PROTO_L2_MODEM:
isdn_tty_at_cout("modem", info);
break;
+ case ISDN_PROTO_L2_FAX:
+ isdn_tty_at_cout("fax", info);
+ break;
default:
isdn_tty_at_cout("unknown", info);
break;
@@ -3107,8 +3272,8 @@
/* &L -Set Numbers to listen on */
p[0]++;
i = 0;
- while ((strchr("0123456789,*[]?;", *p[0])) &&
- (i < ISDN_LMSNLEN))
+ while ((strchr("0123456789,-*[]?;", *p[0])) &&
+ (i < ISDN_LMSNLEN) && *p[0])
m->lmsn[i++] = *p[0]++;
m->lmsn[i] = '\0';
break;
@@ -3264,7 +3429,7 @@
int bval;
mreg = isdn_getnum(p);
- if (mreg < 0 || mreg > ISDN_MODEM_ANZREG)
+ if (mreg < 0 || mreg >= ISDN_MODEM_ANZREG)
PARSE_ERROR1;
switch (*p[0]) {
case '=':
@@ -3338,7 +3503,7 @@
/* If more than one bit set in reg18, autoselect Layer2 */
if ((m->mdmreg[REG_SI1] & m->mdmreg[REG_SI1I]) != m->mdmreg[REG_SI1]) {
if (m->mdmreg[REG_SI1I] == 1) {
- if (l2 != ISDN_PROTO_L2_MODEM)
+ if ((l2 != ISDN_PROTO_L2_MODEM) && (l2 != ISDN_PROTO_L2_FAX))
l2 = ISDN_PROTO_L2_TRANS;
} else
l2 = ISDN_PROTO_L2_X75I;
@@ -3352,6 +3517,12 @@
cmd.driver = info->isdn_driver;
cmd.command = ISDN_CMD_SETL3;
cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
+#ifdef CONFIG_ISDN_TTY_FAX
+ if (l2 == ISDN_PROTO_L2_FAX) {
+ cmd.parm.fax = info->fax;
+ info->fax->direction = ISDN_TTY_FAX_CONN_IN;
+ }
+#endif
isdn_command(&cmd);
cmd.driver = info->isdn_driver;
cmd.arg = info->isdn_channel;
@@ -3372,7 +3543,6 @@
isdn_tty_cmd_PLUSF(char **p, modem_info * info)
{
atemu *m = &info->emu;
- int par;
char rs[20];
if (!strncmp(p[0], "CLASS", 5)) {
@@ -3382,6 +3552,10 @@
p[0]++;
sprintf(rs, "\r\n%d",
(m->mdmreg[REG_SI1] & 1) ? 8 : 0);
+#ifdef CONFIG_ISDN_TTY_FAX
+ if (m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX)
+ sprintf(rs, "\r\n2");
+#endif
isdn_tty_at_cout(rs, info);
break;
case '=':
@@ -3389,23 +3563,37 @@
switch (*p[0]) {
case '0':
p[0]++;
+ m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
+ m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
m->mdmreg[REG_SI1] = 4;
info->xmit_size =
m->mdmreg[REG_PSIZE] * 16;
break;
+#ifdef CONFIG_ISDN_TTY_FAX
case '2':
- printk(KERN_DEBUG "isdn_tty: FCLASS=2\n");
p[0]++;
+ m->mdmreg[REG_SI1] = 1;
+ m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX;
+ m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FAX;
+ info->xmit_size =
+ m->mdmreg[REG_PSIZE] * 16;
break;
+#endif
case '8':
p[0]++;
+ /* L2 will change on dialout with si=1 */
+ m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
+ m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
m->mdmreg[REG_SI1] = 5;
info->xmit_size = VBUF;
break;
case '?':
p[0]++;
- isdn_tty_at_cout("\r\n0,2,8",
- info);
+#ifdef CONFIG_ISDN_TTY_FAX
+ isdn_tty_at_cout("\r\n0,2,8", info);
+#else
+ isdn_tty_at_cout("\r\n0,8", info);
+#endif
break;
default:
PARSE_ERROR1;
@@ -3416,115 +3604,11 @@
}
return 0;
}
- if (!strncmp(p[0], "AA", 2)) {
- p[0] += 2;
- switch (*p[0]) {
- case '?':
- p[0]++;
- sprintf(rs, "\r\n%d",
- m->mdmreg[REG_RINGATA]);
- isdn_tty_at_cout(rs, info);
- break;
- case '=':
- p[0]++;
- par = isdn_getnum(p);
- if ((par < 0) || (par > 255))
- PARSE_ERROR1;
- m->mdmreg[REG_RINGATA] = par;
- break;
- default:
- PARSE_ERROR1;
- }
- return 0;
- }
- if (!strncmp(p[0], "TBC=", 4)) { /* UNKLAR !! */
- p[0] += 4;
- printk(KERN_DEBUG "isdn_tty: Fax FTBC=%c\n", *p[0]);
- switch (*p[0]) {
- case '0':
- p[0]++;
- break;
- default:
- PARSE_ERROR1;
- }
- return 0;
- }
- if (!strncmp(p[0], "BOR=", 4)) { /* UNKLAR !! */
- p[0] += 4;
- printk(KERN_DEBUG "isdn_tty: Fax FBOR=%c\n", *p[0]);
- switch (*p[0]) {
- case '0':
- p[0]++;
- break;
- default:
- PARSE_ERROR1;
- }
- return 0;
- }
- if (!strncmp(p[0], "DCC=", 4)) { /* SETUP irgendwie !! */
- int i, val[]={0,0,0,0,0,0,0,0};
-
- p[0] += 4;
- if (*p[0] == '?') {
- isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0,1),(0),(0),(0-7)",info);
- p[0]++;
- } else {
- for (i=0; (*p[0]>='0') && (*p[0]<='9'); i++) {
- val[i] = *p[0] - 48;
- p[0]++;
- if (*p[0] == ',')
- p[0]++;
- }
- printk(KERN_DEBUG "isdn_tty: Fax Setup values=%d,%d,%d,%d,%d,%d,%d,%d\n",
- val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]);
- }
- return 0;
- }
- if (!strncmp(p[0], "LID=", 4)) { /* set sender ID !! */
- char senderID[80];
- int i;
-
- p[0] += 4;
- if (*p[0] =='"')
- p[0]++;
- for(i=0; (*p[0]) && (*p[0] != '"'); i++)
- senderID[i] = *p[0]++;
- senderID[i] = 0;
- if (*p[0] =='"')
- p[0]++;
- printk(KERN_DEBUG "isdn_tty: Fax sender=>%s<\n", senderID);
- return 0;
- }
- if (!strncmp(p[0], "MFR?", 4)) {
- p[0] += 4;
- printk(KERN_DEBUG "isdn_tty: FMFR?\n");
- isdn_tty_at_cout("\r\nISDNfax", info);
- return 0;
- }
- if (!strncmp(p[0], "MDL?", 4)) {
- p[0] += 4;
- printk(KERN_DEBUG "isdn_tty: FMDL?\n");
- isdn_tty_at_cout("\r\nAVM-B1", info);
- return 0;
- }
- if (!strncmp(p[0], "AP=?", 4)) {
- p[0] += 4;
- printk(KERN_DEBUG "isdn_tty: FAP=?\n");
- return 0;
- }
- if (!strncmp(p[0], "PHCTO=", 6)) {
- /* beim trace mit dem zyxel folgt der wert 30 ;*/
- p[0] += 6;
- printk(KERN_DEBUG "isdn_tty: FPHCTO=%s\n", p[0]);
- return 0;
- }
- if (!strncmp(p[0], "CR=", 3)) {
- p[0] += 3;
- printk(KERN_DEBUG "isdn_tty: FCR=%s\n", p[0]);
- return 0;
- }
- printk(KERN_DEBUG "isdn_tty: unknown token=>AT+F%s<\n", p[0]);
+#ifdef CONFIG_ISDN_TTY_FAX
+ return (isdn_tty_cmd_PLUSF_FAX(p, info));
+#else
PARSE_ERROR1;
+#endif
}
/*
@@ -3534,8 +3618,9 @@
isdn_tty_cmd_PLUSV(char **p, modem_info * info)
{
atemu *m = &info->emu;
+ isdn_ctrl cmd;
static char *vcmd[] =
- {"NH", "IP", "LS", "RX", "SD", "SM", "TX", NULL};
+ {"NH", "IP", "LS", "RX", "SD", "SM", "TX", "DD", NULL};
int i;
int par1;
int par2;
@@ -3711,9 +3796,9 @@
info);
isdn_tty_at_cout("4;ADPCM;4;0;(8000)\r\n",
info);
- isdn_tty_at_cout("5;ALAW;8;0;(8000)",
+ isdn_tty_at_cout("5;ALAW;8;0;(8000)\r\n",
info);
- isdn_tty_at_cout("6;ULAW;8;0;(8000)",
+ isdn_tty_at_cout("6;ULAW;8;0;(8000)\r\n",
info);
break;
default:
@@ -3752,6 +3837,52 @@
isdn_tty_modem_result(1, info);
return 0;
break;
+ case 7:
+ /* AT+VDD - DTMF detection */
+ switch (*p[0]) {
+ case '?':
+ p[0]++;
+ sprintf(rs, "\r\n<%d>,<%d>",
+ m->vpar[4],
+ m->vpar[5]);
+ isdn_tty_at_cout(rs, info);
+ break;
+ case '=':
+ p[0]++;
+ if ((*p[0]>='0') && (*p[0]<='9')) {
+ if (info->online != 1)
+ PARSE_ERROR1;
+ par1 = isdn_getnum(p);
+ if ((par1 < 0) || (par1 > 15))
+ PARSE_ERROR1;
+ if (*p[0] != ',')
+ PARSE_ERROR1;
+ p[0]++;
+ par2 = isdn_getnum(p);
+ if ((par2 < 0) || (par2 > 255))
+ PARSE_ERROR1;
+ m->vpar[4] = par1;
+ m->vpar[5] = par2;
+ cmd.driver = info->isdn_driver;
+ cmd.command = ISDN_CMD_AUDIO;
+ cmd.arg = info->isdn_channel + (ISDN_AUDIO_SETDD << 8);
+ cmd.parm.num[0] = par1;
+ cmd.parm.num[1] = par2;
+ isdn_command(&cmd);
+ break;
+ } else
+ if (*p[0] == '?') {
+ p[0]++;
+ isdn_tty_at_cout("\r\n<0-15>,<0-255>",
+ info);
+ break;
+ } else
+ PARSE_ERROR1;
+ break;
+ default:
+ PARSE_ERROR1;
+ }
+ break;
default:
PARSE_ERROR1;
}
@@ -3774,6 +3905,9 @@
#endif
for (p = &m->mdmcmd[2]; *p;) {
switch (*p) {
+ case ' ':
+ p++;
+ break;
case 'A':
/* A - Accept incoming call */
p++;
@@ -3919,8 +4053,10 @@
isdn_tty_suspend(ds, info, m);
break;
case 'R': /* RESUME */
+ p++;
isdn_tty_get_msnstr(ds, &p);
isdn_tty_resume(ds, info, m);
+ break;
case 'M': /* MESSAGE */
p++;
isdn_tty_send_msg(info, m, p);
@@ -3981,7 +4117,7 @@
eb[1] = 0;
isdn_tty_at_cout(eb, info);
}
- if (m->mdmcmdl >= 2)
+ if ((m->mdmcmdl >= 2) && (!(strncmp(m->mdmcmd, "AT", 2))))
isdn_tty_parse_at(info);
m->mdmcmdl = 0;
continue;
@@ -4007,15 +4143,16 @@
switch (m->mdmcmdl) {
case 0:
if (c == 'A')
- m->mdmcmd[m->mdmcmdl++] = c;
+ m->mdmcmd[m->mdmcmdl] = c;
break;
case 1:
if (c == 'T')
- m->mdmcmd[m->mdmcmdl++] = c;
+ m->mdmcmd[m->mdmcmdl] = c;
break;
default:
- m->mdmcmd[m->mdmcmdl++] = c;
+ m->mdmcmd[m->mdmcmdl] = c;
}
+ m->mdmcmd[++m->mdmcmdl] = 0;
}
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)