1/* 2 * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel). 3 * 4 * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) 5 * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg 6 * 7 * This software may be used and distributed according to the terms 8 * of the GNU General Public License, incorporated herein by reference. 9 * 10 */ 11#undef ISDN_TTY_STAT_DEBUG 12 13#include <linux/isdn.h> 14#include <linux/serial.h> /* ASYNC_* flags */ 15#include <linux/slab.h> 16#include <linux/delay.h> 17#include <linux/mutex.h> 18#include "isdn_common.h" 19#include "isdn_tty.h" 20#ifdef CONFIG_ISDN_AUDIO 21#include "isdn_audio.h" 22#define VBUF 0x3e0 23#define VBUFX (VBUF/16) 24#endif 25 26#define FIX_FILE_TRANSFER 27#define DUMMY_HAYES_AT 28 29/* Prototypes */ 30 31static DEFINE_MUTEX(modem_info_mutex); 32static int isdn_tty_edit_at(const char *, int, modem_info *); 33static void isdn_tty_check_esc(const u_char *, u_char, int, int *, u_long *); 34static void isdn_tty_modem_reset_regs(modem_info *, int); 35static void isdn_tty_cmd_ATA(modem_info *); 36static void isdn_tty_flush_buffer(struct tty_struct *); 37static void isdn_tty_modem_result(int, modem_info *); 38#ifdef CONFIG_ISDN_AUDIO 39static int isdn_tty_countDLE(unsigned char *, int); 40#endif 41 42/* Leave this unchanged unless you know what you do! */ 43#define MODEM_PARANOIA_CHECK 44#define MODEM_DO_RESTART 45 46static int bit2si[8] = 47{1, 5, 7, 7, 7, 7, 7, 7}; 48static int si2bit[8] = 49{4, 1, 4, 4, 4, 4, 4, 4}; 50 51/* isdn_tty_try_read() is called from within isdn_tty_rcv_skb() 52 * to stuff incoming data directly into a tty's flip-buffer. This 53 * is done to speed up tty-receiving if the receive-queue is empty. 54 * This routine MUST be called with interrupts off. 55 * Return: 56 * 1 = Success 57 * 0 = Failure, data has to be buffered and later processed by 58 * isdn_tty_readmodem(). 59 */ 60static int 61isdn_tty_try_read(modem_info *info, struct sk_buff *skb) 62{ 63 struct tty_port *port = &info->port; 64 int c; 65 int len; 66 char last; 67 68 if (!info->online) 69 return 0; 70 71 if (!(info->mcr & UART_MCR_RTS)) 72 return 0; 73 74 len = skb->len 75#ifdef CONFIG_ISDN_AUDIO 76 + ISDN_AUDIO_SKB_DLECOUNT(skb) 77#endif 78 ; 79 80 c = tty_buffer_request_room(port, len); 81 if (c < len) 82 return 0; 83 84#ifdef CONFIG_ISDN_AUDIO 85 if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { 86 int l = skb->len; 87 unsigned char *dp = skb->data; 88 while (--l) { 89 if (*dp == DLE) 90 tty_insert_flip_char(port, DLE, 0); 91 tty_insert_flip_char(port, *dp++, 0); 92 } 93 if (*dp == DLE) 94 tty_insert_flip_char(port, DLE, 0); 95 last = *dp; 96 } else { 97#endif 98 if (len > 1) 99 tty_insert_flip_string(port, skb->data, len - 1); 100 last = skb->data[len - 1]; 101#ifdef CONFIG_ISDN_AUDIO 102 } 103#endif 104 if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) 105 tty_insert_flip_char(port, last, 0xFF); 106 else 107 tty_insert_flip_char(port, last, TTY_NORMAL); 108 tty_flip_buffer_push(port); 109 kfree_skb(skb); 110 111 return 1; 112} 113 114/* isdn_tty_readmodem() is called periodically from within timer-interrupt. 115 * It tries getting received data from the receive queue an stuff it into 116 * the tty's flip-buffer. 117 */ 118void 119isdn_tty_readmodem(void) 120{ 121 int resched = 0; 122 int midx; 123 int i; 124 int r; 125 modem_info *info; 126 127 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 128 midx = dev->m_idx[i]; 129 if (midx < 0) 130 continue; 131 132 info = &dev->mdm.info[midx]; 133 if (!info->online) 134 continue; 135 136 r = 0; 137#ifdef CONFIG_ISDN_AUDIO 138 isdn_audio_eval_dtmf(info); 139 if ((info->vonline & 1) && (info->emu.vpar[1])) 140 isdn_audio_eval_silence(info); 141#endif 142 if (info->mcr & UART_MCR_RTS) { 143 /* CISCO AsyncPPP Hack */ 144 if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) 145 r = isdn_readbchan_tty(info->isdn_driver, 146 info->isdn_channel, 147 &info->port, 0); 148 else 149 r = isdn_readbchan_tty(info->isdn_driver, 150 info->isdn_channel, 151 &info->port, 1); 152 if (r) 153 tty_flip_buffer_push(&info->port); 154 } else 155 r = 1; 156 157 if (r) { 158 info->rcvsched = 0; 159 resched = 1; 160 } else 161 info->rcvsched = 1; 162 } 163 if (!resched) 164 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 0); 165} 166 167int 168isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) 169{ 170 ulong flags; 171 int midx; 172#ifdef CONFIG_ISDN_AUDIO 173 int ifmt; 174#endif 175 modem_info *info; 176 177 if ((midx = dev->m_idx[i]) < 0) { 178 /* if midx is invalid, packet is not for tty */ 179 return 0; 180 } 181 info = &dev->mdm.info[midx]; 182#ifdef CONFIG_ISDN_AUDIO 183 ifmt = 1; 184 185 if ((info->vonline) && (!info->emu.vpar[4])) 186 isdn_audio_calc_dtmf(info, skb->data, skb->len, ifmt); 187 if ((info->vonline & 1) && (info->emu.vpar[1])) 188 isdn_audio_calc_silence(info, skb->data, skb->len, ifmt); 189#endif 190 if ((info->online < 2) 191#ifdef CONFIG_ISDN_AUDIO 192 && (!(info->vonline & 1)) 193#endif 194 ) { 195 /* If Modem not listening, drop data */ 196 kfree_skb(skb); 197 return 1; 198 } 199 if (info->emu.mdmreg[REG_T70] & BIT_T70) { 200 if (info->emu.mdmreg[REG_T70] & BIT_T70_EXT) { 201 /* T.70 decoding: throw away the T.70 header (2 or 4 bytes) */ 202 if (skb->data[0] == 3) /* pure data packet -> 4 byte headers */ 203 skb_pull(skb, 4); 204 else 205 if (skb->data[0] == 1) /* keepalive packet -> 2 byte hdr */ 206 skb_pull(skb, 2); 207 } else 208 /* T.70 decoding: Simply throw away the T.70 header (4 bytes) */ 209 if ((skb->data[0] == 1) && ((skb->data[1] == 0) || (skb->data[1] == 1))) 210 skb_pull(skb, 4); 211 } 212#ifdef CONFIG_ISDN_AUDIO 213 ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; 214 ISDN_AUDIO_SKB_LOCK(skb) = 0; 215 if (info->vonline & 1) { 216 /* voice conversion/compression */ 217 switch (info->emu.vpar[3]) { 218 case 2: 219 case 3: 220 case 4: 221 /* adpcm 222 * Since compressed data takes less 223 * space, we can overwrite the buffer. 224 */ 225 skb_trim(skb, isdn_audio_xlaw2adpcm(info->adpcmr, 226 ifmt, 227 skb->data, 228 skb->data, 229 skb->len)); 230 break; 231 case 5: 232 /* a-law */ 233 if (!ifmt) 234 isdn_audio_ulaw2alaw(skb->data, skb->len); 235 break; 236 case 6: 237 /* u-law */ 238 if (ifmt) 239 isdn_audio_alaw2ulaw(skb->data, skb->len); 240 break; 241 } 242 ISDN_AUDIO_SKB_DLECOUNT(skb) = 243 isdn_tty_countDLE(skb->data, skb->len); 244 } 245#ifdef CONFIG_ISDN_TTY_FAX 246 else { 247 if (info->faxonline & 2) { 248 isdn_tty_fax_bitorder(info, skb); 249 ISDN_AUDIO_SKB_DLECOUNT(skb) = 250 isdn_tty_countDLE(skb->data, skb->len); 251 } 252 } 253#endif 254#endif 255 /* Try to deliver directly via tty-buf if queue is empty */ 256 spin_lock_irqsave(&info->readlock, flags); 257 if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) 258 if (isdn_tty_try_read(info, skb)) { 259 spin_unlock_irqrestore(&info->readlock, flags); 260 return 1; 261 } 262 /* Direct deliver failed or queue wasn't empty. 263 * Queue up for later dequeueing via timer-irq. 264 */ 265 __skb_queue_tail(&dev->drv[di]->rpqueue[channel], skb); 266 dev->drv[di]->rcvcount[channel] += 267 (skb->len 268#ifdef CONFIG_ISDN_AUDIO 269 + ISDN_AUDIO_SKB_DLECOUNT(skb) 270#endif 271 ); 272 spin_unlock_irqrestore(&info->readlock, flags); 273 /* Schedule dequeuing */ 274 if ((dev->modempoll) && (info->rcvsched)) 275 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); 276 return 1; 277} 278 279static void 280isdn_tty_cleanup_xmit(modem_info *info) 281{ 282 skb_queue_purge(&info->xmit_queue); 283#ifdef CONFIG_ISDN_AUDIO 284 skb_queue_purge(&info->dtmf_queue); 285#endif 286} 287 288static void 289isdn_tty_tint(modem_info *info) 290{ 291 struct sk_buff *skb = skb_dequeue(&info->xmit_queue); 292 int len, slen; 293 294 if (!skb) 295 return; 296 len = skb->len; 297 if ((slen = isdn_writebuf_skb_stub(info->isdn_driver, 298 info->isdn_channel, 1, skb)) == len) { 299 struct tty_struct *tty = info->port.tty; 300 info->send_outstanding++; 301 info->msr &= ~UART_MSR_CTS; 302 info->lsr &= ~UART_LSR_TEMT; 303 tty_wakeup(tty); 304 return; 305 } 306 if (slen < 0) { 307 /* Error: no channel, already shutdown, or wrong parameter */ 308 dev_kfree_skb(skb); 309 return; 310 } 311 skb_queue_head(&info->xmit_queue, skb); 312} 313 314#ifdef CONFIG_ISDN_AUDIO 315static int 316isdn_tty_countDLE(unsigned char *buf, int len) 317{ 318 int count = 0; 319 320 while (len--) 321 if (*buf++ == DLE) 322 count++; 323 return count; 324} 325 326/* This routine is called from within isdn_tty_write() to perform 327 * DLE-decoding when sending audio-data. 328 */ 329static int 330isdn_tty_handleDLEdown(modem_info *info, atemu *m, int len) 331{ 332 unsigned char *p = &info->port.xmit_buf[info->xmit_count]; 333 int count = 0; 334 335 while (len > 0) { 336 if (m->lastDLE) { 337 m->lastDLE = 0; 338 switch (*p) { 339 case DLE: 340 /* Escape code */ 341 if (len > 1) 342 memmove(p, p + 1, len - 1); 343 p--; 344 count++; 345 break; 346 case ETX: 347 /* End of data */ 348 info->vonline |= 4; 349 return count; 350 case DC4: 351 /* Abort RX */ 352 info->vonline &= ~1; 353#ifdef ISDN_DEBUG_MODEM_VOICE 354 printk(KERN_DEBUG 355 "DLEdown: got DLE-DC4, send DLE-ETX on ttyI%d\n", 356 info->line); 357#endif 358 isdn_tty_at_cout("\020\003", info); 359 if (!info->vonline) { 360#ifdef ISDN_DEBUG_MODEM_VOICE 361 printk(KERN_DEBUG 362 "DLEdown: send VCON on ttyI%d\n", 363 info->line); 364#endif 365 isdn_tty_at_cout("\r\nVCON\r\n", info); 366 } 367 /* Fall through */ 368 case 'q': 369 case 's': 370 /* Silence */ 371 if (len > 1) 372 memmove(p, p + 1, len - 1); 373 p--; 374 break; 375 } 376 } else { 377 if (*p == DLE) 378 m->lastDLE = 1; 379 else 380 count++; 381 } 382 p++; 383 len--; 384 } 385 if (len < 0) { 386 printk(KERN_WARNING "isdn_tty: len<0 in DLEdown\n"); 387 return 0; 388 } 389 return count; 390} 391 392/* This routine is called from within isdn_tty_write() when receiving 393 * audio-data. It interrupts receiving, if an character other than 394 * ^S or ^Q is sent. 395 */ 396static int 397isdn_tty_end_vrx(const char *buf, int c) 398{ 399 char ch; 400 401 while (c--) { 402 ch = *buf; 403 if ((ch != 0x11) && (ch != 0x13)) 404 return 1; 405 buf++; 406 } 407 return 0; 408} 409 410static int voice_cf[7] = 411{0, 0, 4, 3, 2, 0, 0}; 412 413#endif /* CONFIG_ISDN_AUDIO */ 414 415/* isdn_tty_senddown() is called either directly from within isdn_tty_write() 416 * or via timer-interrupt from within isdn_tty_modem_xmit(). It pulls 417 * outgoing data from the tty's xmit-buffer, handles voice-decompression or 418 * T.70 if necessary, and finally queues it up for sending via isdn_tty_tint. 419 */ 420static void 421isdn_tty_senddown(modem_info *info) 422{ 423 int buflen; 424 int skb_res; 425#ifdef CONFIG_ISDN_AUDIO 426 int audio_len; 427#endif 428 struct sk_buff *skb; 429 430#ifdef CONFIG_ISDN_AUDIO 431 if (info->vonline & 4) { 432 info->vonline &= ~6; 433 if (!info->vonline) { 434#ifdef ISDN_DEBUG_MODEM_VOICE 435 printk(KERN_DEBUG 436 "senddown: send VCON on ttyI%d\n", 437 info->line); 438#endif 439 isdn_tty_at_cout("\r\nVCON\r\n", info); 440 } 441 } 442#endif 443 if (!(buflen = info->xmit_count)) 444 return; 445 if ((info->emu.mdmreg[REG_CTS] & BIT_CTS) != 0) 446 info->msr &= ~UART_MSR_CTS; 447 info->lsr &= ~UART_LSR_TEMT; 448 /* info->xmit_count is modified here and in isdn_tty_write(). 449 * So we return here if isdn_tty_write() is in the 450 * critical section. 451 */ 452 atomic_inc(&info->xmit_lock); 453 if (!(atomic_dec_and_test(&info->xmit_lock))) 454 return; 455 if (info->isdn_driver < 0) { 456 info->xmit_count = 0; 457 return; 458 } 459 skb_res = dev->drv[info->isdn_driver]->interface->hl_hdrlen + 4; 460#ifdef CONFIG_ISDN_AUDIO 461 if (info->vonline & 2) 462 audio_len = buflen * voice_cf[info->emu.vpar[3]]; 463 else 464 audio_len = 0; 465 skb = dev_alloc_skb(skb_res + buflen + audio_len); 466#else 467 skb = dev_alloc_skb(skb_res + buflen); 468#endif 469 if (!skb) { 470 printk(KERN_WARNING 471 "isdn_tty: Out of memory in ttyI%d senddown\n", 472 info->line); 473 return; 474 } 475 skb_reserve(skb, skb_res); 476 memcpy(skb_put(skb, buflen), info->port.xmit_buf, buflen); 477 info->xmit_count = 0; 478#ifdef CONFIG_ISDN_AUDIO 479 if (info->vonline & 2) { 480 /* For now, ifmt is fixed to 1 (alaw), since this 481 * is used with ISDN everywhere in the world, except 482 * US, Canada and Japan. 483 * Later, when US-ISDN protocols are implemented, 484 * this setting will depend on the D-channel protocol. 485 */ 486 int ifmt = 1; 487 488 /* voice conversion/decompression */ 489 switch (info->emu.vpar[3]) { 490 case 2: 491 case 3: 492 case 4: 493 /* adpcm, compatible to ZyXel 1496 modem 494 * with ROM revision 6.01 495 */ 496 audio_len = isdn_audio_adpcm2xlaw(info->adpcms, 497 ifmt, 498 skb->data, 499 skb_put(skb, audio_len), 500 buflen); 501 skb_pull(skb, buflen); 502 skb_trim(skb, audio_len); 503 break; 504 case 5: 505 /* a-law */ 506 if (!ifmt) 507 isdn_audio_alaw2ulaw(skb->data, 508 buflen); 509 break; 510 case 6: 511 /* u-law */ 512 if (ifmt) 513 isdn_audio_ulaw2alaw(skb->data, 514 buflen); 515 break; 516 } 517 } 518#endif /* CONFIG_ISDN_AUDIO */ 519 if (info->emu.mdmreg[REG_T70] & BIT_T70) { 520 /* Add T.70 simplified header */ 521 if (info->emu.mdmreg[REG_T70] & BIT_T70_EXT) 522 memcpy(skb_push(skb, 2), "\1\0", 2); 523 else 524 memcpy(skb_push(skb, 4), "\1\0\1\0", 4); 525 } 526 skb_queue_tail(&info->xmit_queue, skb); 527} 528 529/************************************************************ 530 * 531 * Modem-functions 532 * 533 * mostly "stolen" from original Linux-serial.c and friends. 534 * 535 ************************************************************/ 536 537/* The next routine is called once from within timer-interrupt 538 * triggered within isdn_tty_modem_ncarrier(). It calls 539 * isdn_tty_modem_result() to stuff a "NO CARRIER" Message 540 * into the tty's buffer. 541 */ 542static void 543isdn_tty_modem_do_ncarrier(unsigned long data) 544{ 545 modem_info *info = (modem_info *) data; 546 isdn_tty_modem_result(RESULT_NO_CARRIER, info); 547} 548 549/* Next routine is called, whenever the DTR-signal is raised. 550 * It checks the ncarrier-flag, and triggers the above routine 551 * when necessary. The ncarrier-flag is set, whenever DTR goes 552 * low. 553 */ 554static void 555isdn_tty_modem_ncarrier(modem_info *info) 556{ 557 if (info->ncarrier) { 558 info->nc_timer.expires = jiffies + HZ; 559 add_timer(&info->nc_timer); 560 } 561} 562 563/* 564 * return the usage calculated by si and layer 2 protocol 565 */ 566static int 567isdn_calc_usage(int si, int l2) 568{ 569 int usg = ISDN_USAGE_MODEM; 570 571#ifdef CONFIG_ISDN_AUDIO 572 if (si == 1) { 573 switch (l2) { 574 case ISDN_PROTO_L2_MODEM: 575 usg = ISDN_USAGE_MODEM; 576 break; 577#ifdef CONFIG_ISDN_TTY_FAX 578 case ISDN_PROTO_L2_FAX: 579 usg = ISDN_USAGE_FAX; 580 break; 581#endif 582 case ISDN_PROTO_L2_TRANS: 583 default: 584 usg = ISDN_USAGE_VOICE; 585 break; 586 } 587 } 588#endif 589 return (usg); 590} 591 592/* isdn_tty_dial() performs dialing of a tty an the necessary 593 * setup of the lower levels before that. 594 */ 595static void 596isdn_tty_dial(char *n, modem_info *info, atemu *m) 597{ 598 int usg = ISDN_USAGE_MODEM; 599 int si = 7; 600 int l2 = m->mdmreg[REG_L2PROT]; 601 u_long flags; 602 isdn_ctrl cmd; 603 int i; 604 int j; 605 606 for (j = 7; j >= 0; j--) 607 if (m->mdmreg[REG_SI1] & (1 << j)) { 608 si = bit2si[j]; 609 break; 610 } 611 usg = isdn_calc_usage(si, l2); 612#ifdef CONFIG_ISDN_AUDIO 613 if ((si == 1) && 614 (l2 != ISDN_PROTO_L2_MODEM) 615#ifdef CONFIG_ISDN_TTY_FAX 616 && (l2 != ISDN_PROTO_L2_FAX) 617#endif 618 ) { 619 l2 = ISDN_PROTO_L2_TRANS; 620 usg = ISDN_USAGE_VOICE; 621 } 622#endif 623 m->mdmreg[REG_SI1I] = si2bit[si]; 624 spin_lock_irqsave(&dev->lock, flags); 625 i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); 626 if (i < 0) { 627 spin_unlock_irqrestore(&dev->lock, flags); 628 isdn_tty_modem_result(RESULT_NO_DIALTONE, info); 629 } else { 630 info->isdn_driver = dev->drvmap[i]; 631 info->isdn_channel = dev->chanmap[i]; 632 info->drv_index = i; 633 dev->m_idx[i] = info->line; 634 dev->usage[i] |= ISDN_USAGE_OUTGOING; 635 info->last_dir = 1; 636 strcpy(info->last_num, n); 637 isdn_info_update(); 638 spin_unlock_irqrestore(&dev->lock, flags); 639 cmd.driver = info->isdn_driver; 640 cmd.arg = info->isdn_channel; 641 cmd.command = ISDN_CMD_CLREAZ; 642 isdn_command(&cmd); 643 strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver)); 644 cmd.driver = info->isdn_driver; 645 cmd.command = ISDN_CMD_SETEAZ; 646 isdn_command(&cmd); 647 cmd.driver = info->isdn_driver; 648 cmd.command = ISDN_CMD_SETL2; 649 info->last_l2 = l2; 650 cmd.arg = info->isdn_channel + (l2 << 8); 651 isdn_command(&cmd); 652 cmd.driver = info->isdn_driver; 653 cmd.command = ISDN_CMD_SETL3; 654 cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8); 655#ifdef CONFIG_ISDN_TTY_FAX 656 if (l2 == ISDN_PROTO_L2_FAX) { 657 cmd.parm.fax = info->fax; 658 info->fax->direction = ISDN_TTY_FAX_CONN_OUT; 659 } 660#endif 661 isdn_command(&cmd); 662 cmd.driver = info->isdn_driver; 663 cmd.arg = info->isdn_channel; 664 sprintf(cmd.parm.setup.phone, "%s", n); 665 sprintf(cmd.parm.setup.eazmsn, "%s", 666 isdn_map_eaz2msn(m->msn, info->isdn_driver)); 667 cmd.parm.setup.si1 = si; 668 cmd.parm.setup.si2 = m->mdmreg[REG_SI2]; 669 cmd.command = ISDN_CMD_DIAL; 670 info->dialing = 1; 671 info->emu.carrierwait = 0; 672 strcpy(dev->num[i], n); 673 isdn_info_update(); 674 isdn_command(&cmd); 675 isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1); 676 } 677} 678 679/* isdn_tty_hangup() disassociates a tty from the real 680 * ISDN-line (hangup). The usage-status is cleared 681 * and some cleanup is done also. 682 */ 683void 684isdn_tty_modem_hup(modem_info *info, int local) 685{ 686 isdn_ctrl cmd; 687 int di, ch; 688 689 if (!info) 690 return; 691 692 di = info->isdn_driver; 693 ch = info->isdn_channel; 694 if (di < 0 || ch < 0) 695 return; 696 697 info->isdn_driver = -1; 698 info->isdn_channel = -1; 699 700#ifdef ISDN_DEBUG_MODEM_HUP 701 printk(KERN_DEBUG "Mhup ttyI%d\n", info->line); 702#endif 703 info->rcvsched = 0; 704 isdn_tty_flush_buffer(info->port.tty); 705 if (info->online) { 706 info->last_lhup = local; 707 info->online = 0; 708 isdn_tty_modem_result(RESULT_NO_CARRIER, info); 709 } 710#ifdef CONFIG_ISDN_AUDIO 711 info->vonline = 0; 712#ifdef CONFIG_ISDN_TTY_FAX 713 info->faxonline = 0; 714 info->fax->phase = ISDN_FAX_PHASE_IDLE; 715#endif 716 info->emu.vpar[4] = 0; 717 info->emu.vpar[5] = 8; 718 kfree(info->dtmf_state); 719 info->dtmf_state = NULL; 720 kfree(info->silence_state); 721 info->silence_state = NULL; 722 kfree(info->adpcms); 723 info->adpcms = NULL; 724 kfree(info->adpcmr); 725 info->adpcmr = NULL; 726#endif 727 if ((info->msr & UART_MSR_RI) && 728 (info->emu.mdmreg[REG_RUNG] & BIT_RUNG)) 729 isdn_tty_modem_result(RESULT_RUNG, info); 730 info->msr &= ~(UART_MSR_DCD | UART_MSR_RI); 731 info->lsr |= UART_LSR_TEMT; 732 733 if (local) { 734 cmd.driver = di; 735 cmd.command = ISDN_CMD_HANGUP; 736 cmd.arg = ch; 737 isdn_command(&cmd); 738 } 739 740 isdn_all_eaz(di, ch); 741 info->emu.mdmreg[REG_RINGCNT] = 0; 742 isdn_free_channel(di, ch, 0); 743 744 if (info->drv_index >= 0) { 745 dev->m_idx[info->drv_index] = -1; 746 info->drv_index = -1; 747 } 748} 749 750/* 751 * Begin of a CAPI like interface, currently used only for 752 * supplementary service (CAPI 2.0 part III) 753 */ 754#include <linux/isdn/capicmd.h> 755#include <linux/module.h> 756 757int 758isdn_tty_capi_facility(capi_msg *cm) { 759 return (-1); /* dummy */ 760} 761 762/* isdn_tty_suspend() tries to suspend the current tty connection 763 */ 764static void 765isdn_tty_suspend(char *id, modem_info *info, atemu *m) 766{ 767 isdn_ctrl cmd; 768 769 int l; 770 771 if (!info) 772 return; 773 774#ifdef ISDN_DEBUG_MODEM_SERVICES 775 printk(KERN_DEBUG "Msusp ttyI%d\n", info->line); 776#endif 777 l = strlen(id); 778 if ((info->isdn_driver >= 0)) { 779 cmd.parm.cmsg.Length = l + 18; 780 cmd.parm.cmsg.Command = CAPI_FACILITY; 781 cmd.parm.cmsg.Subcommand = CAPI_REQ; 782 cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1; 783 cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */ 784 cmd.parm.cmsg.para[1] = 0; 785 cmd.parm.cmsg.para[2] = l + 3; 786 cmd.parm.cmsg.para[3] = 4; /* 16 bit 0x0004 Suspend */ 787 cmd.parm.cmsg.para[4] = 0; 788 cmd.parm.cmsg.para[5] = l; 789 strncpy(&cmd.parm.cmsg.para[6], id, l); 790 cmd.command = CAPI_PUT_MESSAGE; 791 cmd.driver = info->isdn_driver; 792 cmd.arg = info->isdn_channel; 793 isdn_command(&cmd); 794 } 795} 796 797/* isdn_tty_resume() tries to resume a suspended call 798 * setup of the lower levels before that. unfortunately here is no 799 * checking for compatibility of used protocols implemented by Q931 800 * It does the same things like isdn_tty_dial, the last command 801 * is different, may be we can merge it. 802 */ 803 804static void 805isdn_tty_resume(char *id, modem_info *info, atemu *m) 806{ 807 int usg = ISDN_USAGE_MODEM; 808 int si = 7; 809 int l2 = m->mdmreg[REG_L2PROT]; 810 isdn_ctrl cmd; 811 ulong flags; 812 int i; 813 int j; 814 int l; 815 816 l = strlen(id); 817 for (j = 7; j >= 0; j--) 818 if (m->mdmreg[REG_SI1] & (1 << j)) { 819 si = bit2si[j]; 820 break; 821 } 822 usg = isdn_calc_usage(si, l2); 823#ifdef CONFIG_ISDN_AUDIO 824 if ((si == 1) && 825 (l2 != ISDN_PROTO_L2_MODEM) 826#ifdef CONFIG_ISDN_TTY_FAX 827 && (l2 != ISDN_PROTO_L2_FAX) 828#endif 829 ) { 830 l2 = ISDN_PROTO_L2_TRANS; 831 usg = ISDN_USAGE_VOICE; 832 } 833#endif 834 m->mdmreg[REG_SI1I] = si2bit[si]; 835 spin_lock_irqsave(&dev->lock, flags); 836 i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); 837 if (i < 0) { 838 spin_unlock_irqrestore(&dev->lock, flags); 839 isdn_tty_modem_result(RESULT_NO_DIALTONE, info); 840 } else { 841 info->isdn_driver = dev->drvmap[i]; 842 info->isdn_channel = dev->chanmap[i]; 843 info->drv_index = i; 844 dev->m_idx[i] = info->line; 845 dev->usage[i] |= ISDN_USAGE_OUTGOING; 846 info->last_dir = 1; 847// strcpy(info->last_num, n); 848 isdn_info_update(); 849 spin_unlock_irqrestore(&dev->lock, flags); 850 cmd.driver = info->isdn_driver; 851 cmd.arg = info->isdn_channel; 852 cmd.command = ISDN_CMD_CLREAZ; 853 isdn_command(&cmd); 854 strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver)); 855 cmd.driver = info->isdn_driver; 856 cmd.command = ISDN_CMD_SETEAZ; 857 isdn_command(&cmd); 858 cmd.driver = info->isdn_driver; 859 cmd.command = ISDN_CMD_SETL2; 860 info->last_l2 = l2; 861 cmd.arg = info->isdn_channel + (l2 << 8); 862 isdn_command(&cmd); 863 cmd.driver = info->isdn_driver; 864 cmd.command = ISDN_CMD_SETL3; 865 cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8); 866 isdn_command(&cmd); 867 cmd.driver = info->isdn_driver; 868 cmd.arg = info->isdn_channel; 869 cmd.parm.cmsg.Length = l + 18; 870 cmd.parm.cmsg.Command = CAPI_FACILITY; 871 cmd.parm.cmsg.Subcommand = CAPI_REQ; 872 cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1; 873 cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */ 874 cmd.parm.cmsg.para[1] = 0; 875 cmd.parm.cmsg.para[2] = l + 3; 876 cmd.parm.cmsg.para[3] = 5; /* 16 bit 0x0005 Resume */ 877 cmd.parm.cmsg.para[4] = 0; 878 cmd.parm.cmsg.para[5] = l; 879 strncpy(&cmd.parm.cmsg.para[6], id, l); 880 cmd.command = CAPI_PUT_MESSAGE; 881 info->dialing = 1; 882// strcpy(dev->num[i], n); 883 isdn_info_update(); 884 isdn_command(&cmd); 885 isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1); 886 } 887} 888 889/* isdn_tty_send_msg() sends a message to a HL driver 890 * This is used for hybrid modem cards to send AT commands to it 891 */ 892 893static void 894isdn_tty_send_msg(modem_info *info, atemu *m, char *msg) 895{ 896 int usg = ISDN_USAGE_MODEM; 897 int si = 7; 898 int l2 = m->mdmreg[REG_L2PROT]; 899 isdn_ctrl cmd; 900 ulong flags; 901 int i; 902 int j; 903 int l; 904 905 l = min(strlen(msg), sizeof(cmd.parm) - sizeof(cmd.parm.cmsg) 906 + sizeof(cmd.parm.cmsg.para) - 2); 907 908 if (!l) { 909 isdn_tty_modem_result(RESULT_ERROR, info); 910 return; 911 } 912 for (j = 7; j >= 0; j--) 913 if (m->mdmreg[REG_SI1] & (1 << j)) { 914 si = bit2si[j]; 915 break; 916 } 917 usg = isdn_calc_usage(si, l2); 918#ifdef CONFIG_ISDN_AUDIO 919 if ((si == 1) && 920 (l2 != ISDN_PROTO_L2_MODEM) 921#ifdef CONFIG_ISDN_TTY_FAX 922 && (l2 != ISDN_PROTO_L2_FAX) 923#endif 924 ) { 925 l2 = ISDN_PROTO_L2_TRANS; 926 usg = ISDN_USAGE_VOICE; 927 } 928#endif 929 m->mdmreg[REG_SI1I] = si2bit[si]; 930 spin_lock_irqsave(&dev->lock, flags); 931 i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); 932 if (i < 0) { 933 spin_unlock_irqrestore(&dev->lock, flags); 934 isdn_tty_modem_result(RESULT_NO_DIALTONE, info); 935 } else { 936 info->isdn_driver = dev->drvmap[i]; 937 info->isdn_channel = dev->chanmap[i]; 938 info->drv_index = i; 939 dev->m_idx[i] = info->line; 940 dev->usage[i] |= ISDN_USAGE_OUTGOING; 941 info->last_dir = 1; 942 isdn_info_update(); 943 spin_unlock_irqrestore(&dev->lock, flags); 944 cmd.driver = info->isdn_driver; 945 cmd.arg = info->isdn_channel; 946 cmd.command = ISDN_CMD_CLREAZ; 947 isdn_command(&cmd); 948 strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver)); 949 cmd.driver = info->isdn_driver; 950 cmd.command = ISDN_CMD_SETEAZ; 951 isdn_command(&cmd); 952 cmd.driver = info->isdn_driver; 953 cmd.command = ISDN_CMD_SETL2; 954 info->last_l2 = l2; 955 cmd.arg = info->isdn_channel + (l2 << 8); 956 isdn_command(&cmd); 957 cmd.driver = info->isdn_driver; 958 cmd.command = ISDN_CMD_SETL3; 959 cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8); 960 isdn_command(&cmd); 961 cmd.driver = info->isdn_driver; 962 cmd.arg = info->isdn_channel; 963 cmd.parm.cmsg.Length = l + 14; 964 cmd.parm.cmsg.Command = CAPI_MANUFACTURER; 965 cmd.parm.cmsg.Subcommand = CAPI_REQ; 966 cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1; 967 cmd.parm.cmsg.para[0] = l + 1; 968 strncpy(&cmd.parm.cmsg.para[1], msg, l); 969 cmd.parm.cmsg.para[l + 1] = 0xd; 970 cmd.command = CAPI_PUT_MESSAGE; 971/* info->dialing = 1; 972 strcpy(dev->num[i], n); 973 isdn_info_update(); 974*/ 975 isdn_command(&cmd); 976 } 977} 978 979static inline int 980isdn_tty_paranoia_check(modem_info *info, char *name, const char *routine) 981{ 982#ifdef MODEM_PARANOIA_CHECK 983 if (!info) { 984 printk(KERN_WARNING "isdn_tty: null info_struct for %s in %s\n", 985 name, routine); 986 return 1; 987 } 988 if (info->magic != ISDN_ASYNC_MAGIC) { 989 printk(KERN_WARNING "isdn_tty: bad magic for modem struct %s in %s\n", 990 name, routine); 991 return 1; 992 } 993#endif 994 return 0; 995} 996 997/* 998 * This routine is called to set the UART divisor registers to match 999 * the specified baud rate for a serial port. 1000 */ 1001static void 1002isdn_tty_change_speed(modem_info *info) 1003{ 1004 struct tty_port *port = &info->port; 1005 uint cflag, 1006 cval, 1007 quot; 1008 int i; 1009 1010 if (!port->tty) 1011 return; 1012 cflag = port->tty->termios.c_cflag; 1013 1014 quot = i = cflag & CBAUD; 1015 if (i & CBAUDEX) { 1016 i &= ~CBAUDEX; 1017 if (i < 1 || i > 2) 1018 port->tty->termios.c_cflag &= ~CBAUDEX; 1019 else 1020 i += 15; 1021 } 1022 if (quot) { 1023 info->mcr |= UART_MCR_DTR; 1024 isdn_tty_modem_ncarrier(info); 1025 } else { 1026 info->mcr &= ~UART_MCR_DTR; 1027 if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { 1028#ifdef ISDN_DEBUG_MODEM_HUP 1029 printk(KERN_DEBUG "Mhup in changespeed\n"); 1030#endif 1031 if (info->online) 1032 info->ncarrier = 1; 1033 isdn_tty_modem_reset_regs(info, 0); 1034 isdn_tty_modem_hup(info, 1); 1035 } 1036 return; 1037 } 1038 /* byte size and parity */ 1039 cval = cflag & (CSIZE | CSTOPB); 1040 cval >>= 4; 1041 if (cflag & PARENB) 1042 cval |= UART_LCR_PARITY; 1043 if (!(cflag & PARODD)) 1044 cval |= UART_LCR_EPAR; 1045 1046 if (cflag & CLOCAL) 1047 port->flags &= ~ASYNC_CHECK_CD; 1048 else { 1049 port->flags |= ASYNC_CHECK_CD; 1050 } 1051} 1052 1053static int 1054isdn_tty_startup(modem_info *info) 1055{ 1056 if (info->port.flags & ASYNC_INITIALIZED) 1057 return 0; 1058 isdn_lock_drivers(); 1059#ifdef ISDN_DEBUG_MODEM_OPEN 1060 printk(KERN_DEBUG "starting up ttyi%d ...\n", info->line); 1061#endif 1062 /* 1063 * Now, initialize the UART 1064 */ 1065 info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; 1066 if (info->port.tty) 1067 clear_bit(TTY_IO_ERROR, &info->port.tty->flags); 1068 /* 1069 * and set the speed of the serial port 1070 */ 1071 isdn_tty_change_speed(info); 1072 1073 info->port.flags |= ASYNC_INITIALIZED; 1074 info->msr |= (UART_MSR_DSR | UART_MSR_CTS); 1075 info->send_outstanding = 0; 1076 return 0; 1077} 1078 1079/* 1080 * This routine will shutdown a serial port; interrupts are disabled, and 1081 * DTR is dropped if the hangup on close termio flag is on. 1082 */ 1083static void 1084isdn_tty_shutdown(modem_info *info) 1085{ 1086 if (!(info->port.flags & ASYNC_INITIALIZED)) 1087 return; 1088#ifdef ISDN_DEBUG_MODEM_OPEN 1089 printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line); 1090#endif 1091 isdn_unlock_drivers(); 1092 info->msr &= ~UART_MSR_RI; 1093 if (!info->port.tty || (info->port.tty->termios.c_cflag & HUPCL)) { 1094 info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); 1095 if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { 1096 isdn_tty_modem_reset_regs(info, 0); 1097#ifdef ISDN_DEBUG_MODEM_HUP 1098 printk(KERN_DEBUG "Mhup in isdn_tty_shutdown\n"); 1099#endif 1100 isdn_tty_modem_hup(info, 1); 1101 } 1102 } 1103 if (info->port.tty) 1104 set_bit(TTY_IO_ERROR, &info->port.tty->flags); 1105 1106 info->port.flags &= ~ASYNC_INITIALIZED; 1107} 1108 1109/* isdn_tty_write() is the main send-routine. It is called from the upper 1110 * levels within the kernel to perform sending data. Depending on the 1111 * online-flag it either directs output to the at-command-interpreter or 1112 * to the lower level. Additional tasks done here: 1113 * - If online, check for escape-sequence (+++) 1114 * - If sending audio-data, call isdn_tty_DLEdown() to parse DLE-codes. 1115 * - If receiving audio-data, call isdn_tty_end_vrx() to abort if needed. 1116 * - If dialing, abort dial. 1117 */ 1118static int 1119isdn_tty_write(struct tty_struct *tty, const u_char *buf, int count) 1120{ 1121 int c; 1122 int total = 0; 1123 modem_info *info = (modem_info *) tty->driver_data; 1124 atemu *m = &info->emu; 1125 1126 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_write")) 1127 return 0; 1128 /* See isdn_tty_senddown() */ 1129 atomic_inc(&info->xmit_lock); 1130 while (1) { 1131 c = count; 1132 if (c > info->xmit_size - info->xmit_count) 1133 c = info->xmit_size - info->xmit_count; 1134 if (info->isdn_driver >= 0 && c > dev->drv[info->isdn_driver]->maxbufsize) 1135 c = dev->drv[info->isdn_driver]->maxbufsize; 1136 if (c <= 0) 1137 break; 1138 if ((info->online > 1) 1139#ifdef CONFIG_ISDN_AUDIO 1140 || (info->vonline & 3) 1141#endif 1142 ) { 1143#ifdef CONFIG_ISDN_AUDIO 1144 if (!info->vonline) 1145#endif 1146 isdn_tty_check_esc(buf, m->mdmreg[REG_ESC], c, 1147 &(m->pluscount), 1148 &(m->lastplus)); 1149 memcpy(&info->port.xmit_buf[info->xmit_count], buf, c); 1150#ifdef CONFIG_ISDN_AUDIO 1151 if (info->vonline) { 1152 int cc = isdn_tty_handleDLEdown(info, m, c); 1153 if (info->vonline & 2) { 1154 if (!cc) { 1155 /* If DLE decoding results in zero-transmit, but 1156 * c originally was non-zero, do a wakeup. 1157 */ 1158 tty_wakeup(tty); 1159 info->msr |= UART_MSR_CTS; 1160 info->lsr |= UART_LSR_TEMT; 1161 } 1162 info->xmit_count += cc; 1163 } 1164 if ((info->vonline & 3) == 1) { 1165 /* Do NOT handle Ctrl-Q or Ctrl-S 1166 * when in full-duplex audio mode. 1167 */ 1168 if (isdn_tty_end_vrx(buf, c)) { 1169 info->vonline &= ~1; 1170#ifdef ISDN_DEBUG_MODEM_VOICE 1171 printk(KERN_DEBUG 1172 "got !^Q/^S, send DLE-ETX,VCON on ttyI%d\n", 1173 info->line); 1174#endif 1175 isdn_tty_at_cout("\020\003\r\nVCON\r\n", info); 1176 } 1177 } 1178 } else 1179 if (TTY_IS_FCLASS1(info)) { 1180 int cc = isdn_tty_handleDLEdown(info, m, c); 1181 1182 if (info->vonline & 4) { /* ETX seen */ 1183 isdn_ctrl c; 1184 1185 c.command = ISDN_CMD_FAXCMD; 1186 c.driver = info->isdn_driver; 1187 c.arg = info->isdn_channel; 1188 c.parm.aux.cmd = ISDN_FAX_CLASS1_CTRL; 1189 c.parm.aux.subcmd = ETX; 1190 isdn_command(&c); 1191 } 1192 info->vonline = 0; 1193#ifdef ISDN_DEBUG_MODEM_VOICE 1194 printk(KERN_DEBUG "fax dle cc/c %d/%d\n", cc, c); 1195#endif 1196 info->xmit_count += cc; 1197 } else 1198#endif 1199 info->xmit_count += c; 1200 } else { 1201 info->msr |= UART_MSR_CTS; 1202 info->lsr |= UART_LSR_TEMT; 1203 if (info->dialing) { 1204 info->dialing = 0; 1205#ifdef ISDN_DEBUG_MODEM_HUP 1206 printk(KERN_DEBUG "Mhup in isdn_tty_write\n"); 1207#endif 1208 isdn_tty_modem_result(RESULT_NO_CARRIER, info); 1209 isdn_tty_modem_hup(info, 1); 1210 } else 1211 c = isdn_tty_edit_at(buf, c, info); 1212 } 1213 buf += c; 1214 count -= c; 1215 total += c; 1216 } 1217 atomic_dec(&info->xmit_lock); 1218 if ((info->xmit_count) || !skb_queue_empty(&info->xmit_queue)) { 1219 if (m->mdmreg[REG_DXMT] & BIT_DXMT) { 1220 isdn_tty_senddown(info); 1221 isdn_tty_tint(info); 1222 } 1223 isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1); 1224 } 1225 return total; 1226} 1227 1228static int 1229isdn_tty_write_room(struct tty_struct *tty) 1230{ 1231 modem_info *info = (modem_info *) tty->driver_data; 1232 int ret; 1233 1234 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_write_room")) 1235 return 0; 1236 if (!info->online) 1237 return info->xmit_size; 1238 ret = info->xmit_size - info->xmit_count; 1239 return (ret < 0) ? 0 : ret; 1240} 1241 1242static int 1243isdn_tty_chars_in_buffer(struct tty_struct *tty) 1244{ 1245 modem_info *info = (modem_info *) tty->driver_data; 1246 1247 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_chars_in_buffer")) 1248 return 0; 1249 if (!info->online) 1250 return 0; 1251 return (info->xmit_count); 1252} 1253 1254static void 1255isdn_tty_flush_buffer(struct tty_struct *tty) 1256{ 1257 modem_info *info; 1258 1259 if (!tty) { 1260 return; 1261 } 1262 info = (modem_info *) tty->driver_data; 1263 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_flush_buffer")) { 1264 return; 1265 } 1266 isdn_tty_cleanup_xmit(info); 1267 info->xmit_count = 0; 1268 tty_wakeup(tty); 1269} 1270 1271static void 1272isdn_tty_flush_chars(struct tty_struct *tty) 1273{ 1274 modem_info *info = (modem_info *) tty->driver_data; 1275 1276 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_flush_chars")) 1277 return; 1278 if ((info->xmit_count) || !skb_queue_empty(&info->xmit_queue)) 1279 isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1); 1280} 1281 1282/* 1283 * ------------------------------------------------------------ 1284 * isdn_tty_throttle() 1285 * 1286 * This routine is called by the upper-layer tty layer to signal that 1287 * incoming characters should be throttled. 1288 * ------------------------------------------------------------ 1289 */ 1290static void 1291isdn_tty_throttle(struct tty_struct *tty) 1292{ 1293 modem_info *info = (modem_info *) tty->driver_data; 1294 1295 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_throttle")) 1296 return; 1297 if (I_IXOFF(tty)) 1298 info->x_char = STOP_CHAR(tty); 1299 info->mcr &= ~UART_MCR_RTS; 1300} 1301 1302static void 1303isdn_tty_unthrottle(struct tty_struct *tty) 1304{ 1305 modem_info *info = (modem_info *) tty->driver_data; 1306 1307 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_unthrottle")) 1308 return; 1309 if (I_IXOFF(tty)) { 1310 if (info->x_char) 1311 info->x_char = 0; 1312 else 1313 info->x_char = START_CHAR(tty); 1314 } 1315 info->mcr |= UART_MCR_RTS; 1316} 1317 1318/* 1319 * ------------------------------------------------------------ 1320 * isdn_tty_ioctl() and friends 1321 * ------------------------------------------------------------ 1322 */ 1323 1324/* 1325 * isdn_tty_get_lsr_info - get line status register info 1326 * 1327 * Purpose: Let user call ioctl() to get info when the UART physically 1328 * is emptied. On bus types like RS485, the transmitter must 1329 * release the bus after transmitting. This must be done when 1330 * the transmit shift register is empty, not be done when the 1331 * transmit holding register is empty. This functionality 1332 * allows RS485 driver to be written in user space. 1333 */ 1334static int 1335isdn_tty_get_lsr_info(modem_info *info, uint __user *value) 1336{ 1337 u_char status; 1338 uint result; 1339 1340 status = info->lsr; 1341 result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); 1342 return put_user(result, value); 1343} 1344 1345 1346static int 1347isdn_tty_tiocmget(struct tty_struct *tty) 1348{ 1349 modem_info *info = (modem_info *) tty->driver_data; 1350 u_char control, status; 1351 1352 if (isdn_tty_paranoia_check(info, tty->name, __func__)) 1353 return -ENODEV; 1354 if (tty->flags & (1 << TTY_IO_ERROR)) 1355 return -EIO; 1356 1357 mutex_lock(&modem_info_mutex); 1358#ifdef ISDN_DEBUG_MODEM_IOCTL 1359 printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line); 1360#endif 1361 1362 control = info->mcr; 1363 status = info->msr; 1364 mutex_unlock(&modem_info_mutex); 1365 return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) 1366 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) 1367 | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) 1368 | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) 1369 | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) 1370 | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); 1371} 1372 1373static int 1374isdn_tty_tiocmset(struct tty_struct *tty, 1375 unsigned int set, unsigned int clear) 1376{ 1377 modem_info *info = (modem_info *) tty->driver_data; 1378 1379 if (isdn_tty_paranoia_check(info, tty->name, __func__)) 1380 return -ENODEV; 1381 if (tty->flags & (1 << TTY_IO_ERROR)) 1382 return -EIO; 1383 1384#ifdef ISDN_DEBUG_MODEM_IOCTL 1385 printk(KERN_DEBUG "ttyI%d ioctl TIOCMxxx: %x %x\n", info->line, set, clear); 1386#endif 1387 1388 mutex_lock(&modem_info_mutex); 1389 if (set & TIOCM_RTS) 1390 info->mcr |= UART_MCR_RTS; 1391 if (set & TIOCM_DTR) { 1392 info->mcr |= UART_MCR_DTR; 1393 isdn_tty_modem_ncarrier(info); 1394 } 1395 1396 if (clear & TIOCM_RTS) 1397 info->mcr &= ~UART_MCR_RTS; 1398 if (clear & TIOCM_DTR) { 1399 info->mcr &= ~UART_MCR_DTR; 1400 if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { 1401 isdn_tty_modem_reset_regs(info, 0); 1402#ifdef ISDN_DEBUG_MODEM_HUP 1403 printk(KERN_DEBUG "Mhup in TIOCMSET\n"); 1404#endif 1405 if (info->online) 1406 info->ncarrier = 1; 1407 isdn_tty_modem_hup(info, 1); 1408 } 1409 } 1410 mutex_unlock(&modem_info_mutex); 1411 return 0; 1412} 1413 1414static int 1415isdn_tty_ioctl(struct tty_struct *tty, uint cmd, ulong arg) 1416{ 1417 modem_info *info = (modem_info *) tty->driver_data; 1418 int retval; 1419 1420 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_ioctl")) 1421 return -ENODEV; 1422 if (tty->flags & (1 << TTY_IO_ERROR)) 1423 return -EIO; 1424 switch (cmd) { 1425 case TCSBRK: /* SVID version: non-zero arg --> no break */ 1426#ifdef ISDN_DEBUG_MODEM_IOCTL 1427 printk(KERN_DEBUG "ttyI%d ioctl TCSBRK\n", info->line); 1428#endif 1429 retval = tty_check_change(tty); 1430 if (retval) 1431 return retval; 1432 tty_wait_until_sent(tty, 0); 1433 return 0; 1434 case TCSBRKP: /* support for POSIX tcsendbreak() */ 1435#ifdef ISDN_DEBUG_MODEM_IOCTL 1436 printk(KERN_DEBUG "ttyI%d ioctl TCSBRKP\n", info->line); 1437#endif 1438 retval = tty_check_change(tty); 1439 if (retval) 1440 return retval; 1441 tty_wait_until_sent(tty, 0); 1442 return 0; 1443 case TIOCSERGETLSR: /* Get line status register */ 1444#ifdef ISDN_DEBUG_MODEM_IOCTL 1445 printk(KERN_DEBUG "ttyI%d ioctl TIOCSERGETLSR\n", info->line); 1446#endif 1447 return isdn_tty_get_lsr_info(info, (uint __user *) arg); 1448 default: 1449#ifdef ISDN_DEBUG_MODEM_IOCTL 1450 printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on ttyi%d\n", cmd, info->line); 1451#endif 1452 return -ENOIOCTLCMD; 1453 } 1454 return 0; 1455} 1456 1457static void 1458isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) 1459{ 1460 modem_info *info = (modem_info *) tty->driver_data; 1461 1462 if (!old_termios) 1463 isdn_tty_change_speed(info); 1464 else { 1465 if (tty->termios.c_cflag == old_termios->c_cflag && 1466 tty->termios.c_ispeed == old_termios->c_ispeed && 1467 tty->termios.c_ospeed == old_termios->c_ospeed) 1468 return; 1469 isdn_tty_change_speed(info); 1470 } 1471} 1472 1473/* 1474 * ------------------------------------------------------------ 1475 * isdn_tty_open() and friends 1476 * ------------------------------------------------------------ 1477 */ 1478 1479static int isdn_tty_install(struct tty_driver *driver, struct tty_struct *tty) 1480{ 1481 modem_info *info = &dev->mdm.info[tty->index]; 1482 1483 if (isdn_tty_paranoia_check(info, tty->name, __func__)) 1484 return -ENODEV; 1485 1486 tty->driver_data = info; 1487 1488 return tty_port_install(&info->port, driver, tty); 1489} 1490 1491/* 1492 * This routine is called whenever a serial port is opened. It 1493 * enables interrupts for a serial port, linking in its async structure into 1494 * the IRQ chain. It also performs the serial-specific 1495 * initialization for the tty structure. 1496 */ 1497static int 1498isdn_tty_open(struct tty_struct *tty, struct file *filp) 1499{ 1500 modem_info *info = tty->driver_data; 1501 struct tty_port *port = &info->port; 1502 int retval; 1503 1504#ifdef ISDN_DEBUG_MODEM_OPEN 1505 printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, 1506 port->count); 1507#endif 1508 port->count++; 1509 port->tty = tty; 1510 /* 1511 * Start up serial port 1512 */ 1513 retval = isdn_tty_startup(info); 1514 if (retval) { 1515#ifdef ISDN_DEBUG_MODEM_OPEN 1516 printk(KERN_DEBUG "isdn_tty_open return after startup\n"); 1517#endif 1518 return retval; 1519 } 1520 retval = tty_port_block_til_ready(port, tty, filp); 1521 if (retval) { 1522#ifdef ISDN_DEBUG_MODEM_OPEN 1523 printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n"); 1524#endif 1525 return retval; 1526 } 1527#ifdef ISDN_DEBUG_MODEM_OPEN 1528 printk(KERN_DEBUG "isdn_tty_open ttyi%d successful...\n", info->line); 1529#endif 1530 dev->modempoll++; 1531#ifdef ISDN_DEBUG_MODEM_OPEN 1532 printk(KERN_DEBUG "isdn_tty_open normal exit\n"); 1533#endif 1534 return 0; 1535} 1536 1537static void 1538isdn_tty_close(struct tty_struct *tty, struct file *filp) 1539{ 1540 modem_info *info = (modem_info *) tty->driver_data; 1541 struct tty_port *port = &info->port; 1542 ulong timeout; 1543 1544 if (!info || isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close")) 1545 return; 1546 if (tty_hung_up_p(filp)) { 1547#ifdef ISDN_DEBUG_MODEM_OPEN 1548 printk(KERN_DEBUG "isdn_tty_close return after tty_hung_up_p\n"); 1549#endif 1550 return; 1551 } 1552 if ((tty->count == 1) && (port->count != 1)) { 1553 /* 1554 * Uh, oh. tty->count is 1, which means that the tty 1555 * structure will be freed. Info->count should always 1556 * be one in these conditions. If it's greater than 1557 * one, we've got real problems, since it means the 1558 * serial port won't be shutdown. 1559 */ 1560 printk(KERN_ERR "isdn_tty_close: bad port count; tty->count is 1, " 1561 "info->count is %d\n", port->count); 1562 port->count = 1; 1563 } 1564 if (--port->count < 0) { 1565 printk(KERN_ERR "isdn_tty_close: bad port count for ttyi%d: %d\n", 1566 info->line, port->count); 1567 port->count = 0; 1568 } 1569 if (port->count) { 1570#ifdef ISDN_DEBUG_MODEM_OPEN 1571 printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); 1572#endif 1573 return; 1574 } 1575 port->flags |= ASYNC_CLOSING; 1576 1577 tty->closing = 1; 1578 /* 1579 * At this point we stop accepting input. To do this, we 1580 * disable the receive line status interrupts, and tell the 1581 * interrupt driver to stop checking the data ready bit in the 1582 * line status register. 1583 */ 1584 if (port->flags & ASYNC_INITIALIZED) { 1585 tty_wait_until_sent_from_close(tty, 3000); /* 30 seconds timeout */ 1586 /* 1587 * Before we drop DTR, make sure the UART transmitter 1588 * has completely drained; this is especially 1589 * important if there is a transmit FIFO! 1590 */ 1591 timeout = jiffies + HZ; 1592 while (!(info->lsr & UART_LSR_TEMT)) { 1593 schedule_timeout_interruptible(20); 1594 if (time_after(jiffies, timeout)) 1595 break; 1596 } 1597 } 1598 dev->modempoll--; 1599 isdn_tty_shutdown(info); 1600 isdn_tty_flush_buffer(tty); 1601 tty_ldisc_flush(tty); 1602 port->tty = NULL; 1603 info->ncarrier = 0; 1604 1605 tty_port_close_end(port, tty); 1606#ifdef ISDN_DEBUG_MODEM_OPEN 1607 printk(KERN_DEBUG "isdn_tty_close normal exit\n"); 1608#endif 1609} 1610 1611/* 1612 * isdn_tty_hangup() --- called by tty_hangup() when a hangup is signaled. 1613 */ 1614static void 1615isdn_tty_hangup(struct tty_struct *tty) 1616{ 1617 modem_info *info = (modem_info *) tty->driver_data; 1618 struct tty_port *port = &info->port; 1619 1620 if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_hangup")) 1621 return; 1622 isdn_tty_shutdown(info); 1623 port->count = 0; 1624 port->flags &= ~ASYNC_NORMAL_ACTIVE; 1625 port->tty = NULL; 1626 wake_up_interruptible(&port->open_wait); 1627} 1628 1629/* This routine initializes all emulator-data. 1630 */ 1631static void 1632isdn_tty_reset_profile(atemu *m) 1633{ 1634 m->profile[0] = 0; 1635 m->profile[1] = 0; 1636 m->profile[2] = 43; 1637 m->profile[3] = 13; 1638 m->profile[4] = 10; 1639 m->profile[5] = 8; 1640 m->profile[6] = 3; 1641 m->profile[7] = 60; 1642 m->profile[8] = 2; 1643 m->profile[9] = 6; 1644 m->profile[10] = 7; 1645 m->profile[11] = 70; 1646 m->profile[12] = 0x45; 1647 m->profile[13] = 4; 1648 m->profile[14] = ISDN_PROTO_L2_X75I; 1649 m->profile[15] = ISDN_PROTO_L3_TRANS; 1650 m->profile[16] = ISDN_SERIAL_XMIT_SIZE / 16; 1651 m->profile[17] = ISDN_MODEM_WINSIZE; 1652 m->profile[18] = 4; 1653 m->profile[19] = 0; 1654 m->profile[20] = 0; 1655 m->profile[23] = 0; 1656 m->pmsn[0] = '\0'; 1657 m->plmsn[0] = '\0'; 1658} 1659 1660#ifdef CONFIG_ISDN_AUDIO 1661static void 1662isdn_tty_modem_reset_vpar(atemu *m) 1663{ 1664 m->vpar[0] = 2; /* Voice-device (2 = phone line) */ 1665 m->vpar[1] = 0; /* Silence detection level (0 = none ) */ 1666 m->vpar[2] = 70; /* Silence interval (7 sec. ) */ 1667 m->vpar[3] = 2; /* Compression type (1 = ADPCM-2 ) */ 1668 m->vpar[4] = 0; /* DTMF detection level (0 = softcode ) */ 1669 m->vpar[5] = 8; /* DTMF interval (8 * 5 ms. ) */ 1670} 1671#endif 1672 1673#ifdef CONFIG_ISDN_TTY_FAX 1674static void 1675isdn_tty_modem_reset_faxpar(modem_info *info) 1676{ 1677 T30_s *f = info->fax; 1678 1679 f->code = 0; 1680 f->phase = ISDN_FAX_PHASE_IDLE; 1681 f->direction = 0; 1682 f->resolution = 1; /* fine */ 1683 f->rate = 5; /* 14400 bit/s */ 1684 f->width = 0; 1685 f->length = 0; 1686 f->compression = 0; 1687 f->ecm = 0; 1688 f->binary = 0; 1689 f->scantime = 0; 1690 memset(&f->id[0], 32, FAXIDLEN - 1); 1691 f->id[FAXIDLEN - 1] = 0; 1692 f->badlin = 0; 1693 f->badmul = 0; 1694 f->bor = 0; 1695 f->nbc = 0; 1696 f->cq = 0; 1697 f->cr = 0; 1698 f->ctcrty = 0; 1699 f->minsp = 0; 1700 f->phcto = 30; 1701 f->rel = 0; 1702 memset(&f->pollid[0], 32, FAXIDLEN - 1); 1703 f->pollid[FAXIDLEN - 1] = 0; 1704} 1705#endif 1706 1707static void 1708isdn_tty_modem_reset_regs(modem_info *info, int force) 1709{ 1710 atemu *m = &info->emu; 1711 if ((m->mdmreg[REG_DTRR] & BIT_DTRR) || force) { 1712 memcpy(m->mdmreg, m->profile, ISDN_MODEM_NUMREG); 1713 memcpy(m->msn, m->pmsn, ISDN_MSNLEN); 1714 memcpy(m->lmsn, m->plmsn, ISDN_LMSNLEN); 1715 info->xmit_size = m->mdmreg[REG_PSIZE] * 16; 1716 } 1717#ifdef CONFIG_ISDN_AUDIO 1718 isdn_tty_modem_reset_vpar(m); 1719#endif 1720#ifdef CONFIG_ISDN_TTY_FAX 1721 isdn_tty_modem_reset_faxpar(info); 1722#endif 1723 m->mdmcmdl = 0; 1724} 1725 1726static void 1727modem_write_profile(atemu *m) 1728{ 1729 memcpy(m->profile, m->mdmreg, ISDN_MODEM_NUMREG); 1730 memcpy(m->pmsn, m->msn, ISDN_MSNLEN); 1731 memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN); 1732 if (dev->profd) 1733 send_sig(SIGIO, dev->profd, 1); 1734} 1735 1736static const struct tty_operations modem_ops = { 1737 .install = isdn_tty_install, 1738 .open = isdn_tty_open, 1739 .close = isdn_tty_close, 1740 .write = isdn_tty_write, 1741 .flush_chars = isdn_tty_flush_chars, 1742 .write_room = isdn_tty_write_room, 1743 .chars_in_buffer = isdn_tty_chars_in_buffer, 1744 .flush_buffer = isdn_tty_flush_buffer, 1745 .ioctl = isdn_tty_ioctl, 1746 .throttle = isdn_tty_throttle, 1747 .unthrottle = isdn_tty_unthrottle, 1748 .set_termios = isdn_tty_set_termios, 1749 .hangup = isdn_tty_hangup, 1750 .tiocmget = isdn_tty_tiocmget, 1751 .tiocmset = isdn_tty_tiocmset, 1752}; 1753 1754static int isdn_tty_carrier_raised(struct tty_port *port) 1755{ 1756 modem_info *info = container_of(port, modem_info, port); 1757 return info->msr & UART_MSR_DCD; 1758} 1759 1760static const struct tty_port_operations isdn_tty_port_ops = { 1761 .carrier_raised = isdn_tty_carrier_raised, 1762}; 1763 1764int 1765isdn_tty_modem_init(void) 1766{ 1767 isdn_modem_t *m; 1768 int i, retval; 1769 modem_info *info; 1770 1771 m = &dev->mdm; 1772 m->tty_modem = alloc_tty_driver(ISDN_MAX_CHANNELS); 1773 if (!m->tty_modem) 1774 return -ENOMEM; 1775 m->tty_modem->name = "ttyI"; 1776 m->tty_modem->major = ISDN_TTY_MAJOR; 1777 m->tty_modem->minor_start = 0; 1778 m->tty_modem->type = TTY_DRIVER_TYPE_SERIAL; 1779 m->tty_modem->subtype = SERIAL_TYPE_NORMAL; 1780 m->tty_modem->init_termios = tty_std_termios; 1781 m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1782 m->tty_modem->flags = TTY_DRIVER_REAL_RAW; 1783 m->tty_modem->driver_name = "isdn_tty"; 1784 tty_set_operations(m->tty_modem, &modem_ops); 1785 retval = tty_register_driver(m->tty_modem); 1786 if (retval) { 1787 printk(KERN_WARNING "isdn_tty: Couldn't register modem-device\n"); 1788 goto err; 1789 } 1790 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1791 info = &m->info[i]; 1792#ifdef CONFIG_ISDN_TTY_FAX 1793 if (!(info->fax = kmalloc(sizeof(T30_s), GFP_KERNEL))) { 1794 printk(KERN_ERR "Could not allocate fax t30-buffer\n"); 1795 retval = -ENOMEM; 1796 goto err_unregister; 1797 } 1798#endif 1799 tty_port_init(&info->port); 1800 info->port.ops = &isdn_tty_port_ops; 1801 spin_lock_init(&info->readlock); 1802 sprintf(info->last_cause, "0000"); 1803 sprintf(info->last_num, "none"); 1804 info->last_dir = 0; 1805 info->last_lhup = 1; 1806 info->last_l2 = -1; 1807 info->last_si = 0; 1808 isdn_tty_reset_profile(&info->emu); 1809 isdn_tty_modem_reset_regs(info, 1); 1810 info->magic = ISDN_ASYNC_MAGIC; 1811 info->line = i; 1812 info->x_char = 0; 1813 info->isdn_driver = -1; 1814 info->isdn_channel = -1; 1815 info->drv_index = -1; 1816 info->xmit_size = ISDN_SERIAL_XMIT_SIZE; 1817 init_timer(&info->nc_timer); 1818 info->nc_timer.function = isdn_tty_modem_do_ncarrier; 1819 info->nc_timer.data = (unsigned long) info; 1820 skb_queue_head_init(&info->xmit_queue); 1821#ifdef CONFIG_ISDN_AUDIO 1822 skb_queue_head_init(&info->dtmf_queue); 1823#endif 1824 info->port.xmit_buf = kmalloc(ISDN_SERIAL_XMIT_MAX + 5, 1825 GFP_KERNEL); 1826 if (!info->port.xmit_buf) { 1827 printk(KERN_ERR "Could not allocate modem xmit-buffer\n"); 1828 retval = -ENOMEM; 1829 goto err_unregister; 1830 } 1831 /* Make room for T.70 header */ 1832 info->port.xmit_buf += 4; 1833 } 1834 return 0; 1835err_unregister: 1836 for (i--; i >= 0; i--) { 1837 info = &m->info[i]; 1838#ifdef CONFIG_ISDN_TTY_FAX 1839 kfree(info->fax); 1840#endif 1841 kfree(info->port.xmit_buf - 4); 1842 info->port.xmit_buf = NULL; 1843 tty_port_destroy(&info->port); 1844 } 1845 tty_unregister_driver(m->tty_modem); 1846err: 1847 put_tty_driver(m->tty_modem); 1848 m->tty_modem = NULL; 1849 return retval; 1850} 1851 1852void 1853isdn_tty_exit(void) 1854{ 1855 modem_info *info; 1856 int i; 1857 1858 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1859 info = &dev->mdm.info[i]; 1860 isdn_tty_cleanup_xmit(info); 1861#ifdef CONFIG_ISDN_TTY_FAX 1862 kfree(info->fax); 1863#endif 1864 kfree(info->port.xmit_buf - 4); 1865 info->port.xmit_buf = NULL; 1866 tty_port_destroy(&info->port); 1867 } 1868 tty_unregister_driver(dev->mdm.tty_modem); 1869 put_tty_driver(dev->mdm.tty_modem); 1870 dev->mdm.tty_modem = NULL; 1871} 1872 1873 1874/* 1875 * isdn_tty_match_icall(char *MSN, atemu *tty_emulator, int dev_idx) 1876 * match the MSN against the MSNs (glob patterns) defined for tty_emulator, 1877 * and return 0 for match, 1 for no match, 2 if MSN could match if longer. 1878 */ 1879 1880static int 1881isdn_tty_match_icall(char *cid, atemu *emu, int di) 1882{ 1883#ifdef ISDN_DEBUG_MODEM_ICALL 1884 printk(KERN_DEBUG "m_fi: msn=%s lmsn=%s mmsn=%s mreg[SI1]=%d mreg[SI2]=%d\n", 1885 emu->msn, emu->lmsn, isdn_map_eaz2msn(emu->msn, di), 1886 emu->mdmreg[REG_SI1], emu->mdmreg[REG_SI2]); 1887#endif 1888 if (strlen(emu->lmsn)) { 1889 char *p = emu->lmsn; 1890 char *q; 1891 int tmp; 1892 int ret = 0; 1893 1894 while (1) { 1895 if ((q = strchr(p, ';'))) 1896 *q = '\0'; 1897 if ((tmp = isdn_msncmp(cid, isdn_map_eaz2msn(p, di))) > ret) 1898 ret = tmp; 1899#ifdef ISDN_DEBUG_MODEM_ICALL 1900 printk(KERN_DEBUG "m_fi: lmsnX=%s mmsn=%s -> tmp=%d\n", 1901 p, isdn_map_eaz2msn(emu->msn, di), tmp); 1902#endif 1903 if (q) { 1904 *q = ';'; 1905 p = q; 1906 p++; 1907 } 1908 if (!tmp) 1909 return 0; 1910 if (!q) 1911 break; 1912 } 1913 return ret; 1914 } else { 1915 int tmp; 1916 tmp = isdn_msncmp(cid, isdn_map_eaz2msn(emu->msn, di)); 1917#ifdef ISDN_DEBUG_MODEM_ICALL 1918 printk(KERN_DEBUG "m_fi: mmsn=%s -> tmp=%d\n", 1919 isdn_map_eaz2msn(emu->msn, di), tmp); 1920#endif 1921 return tmp; 1922 } 1923} 1924 1925/* 1926 * An incoming call-request has arrived. 1927 * Search the tty-devices for an appropriate device and bind 1928 * it to the ISDN-Channel. 1929 * Return: 1930 * 1931 * 0 = No matching device found. 1932 * 1 = A matching device found. 1933 * 3 = No match found, but eventually would match, if 1934 * CID is longer. 1935 */ 1936int 1937isdn_tty_find_icall(int di, int ch, setup_parm *setup) 1938{ 1939 char *eaz; 1940 int i; 1941 int wret; 1942 int idx; 1943 int si1; 1944 int si2; 1945 char *nr; 1946 ulong flags; 1947 1948 if (!setup->phone[0]) { 1949 nr = "0"; 1950 printk(KERN_INFO "isdn_tty: Incoming call without OAD, assuming '0'\n"); 1951 } else 1952 nr = setup->phone; 1953 si1 = (int) setup->si1; 1954 si2 = (int) setup->si2; 1955 if (!setup->eazmsn[0]) { 1956 printk(KERN_WARNING "isdn_tty: Incoming call without CPN, assuming '0'\n"); 1957 eaz = "0"; 1958 } else 1959 eaz = setup->eazmsn; 1960#ifdef ISDN_DEBUG_MODEM_ICALL 1961 printk(KERN_DEBUG "m_fi: eaz=%s si1=%d si2=%d\n", eaz, si1, si2); 1962#endif 1963 wret = 0; 1964 spin_lock_irqsave(&dev->lock, flags); 1965 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1966 modem_info *info = &dev->mdm.info[i]; 1967 1968 if (info->port.count == 0) 1969 continue; 1970 if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) && /* SI1 is matching */ 1971 (info->emu.mdmreg[REG_SI2] == si2)) { /* SI2 is matching */ 1972 idx = isdn_dc2minor(di, ch); 1973#ifdef ISDN_DEBUG_MODEM_ICALL 1974 printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret); 1975 printk(KERN_DEBUG "m_fi: idx=%d flags=%08lx drv=%d ch=%d usg=%d\n", idx, 1976 info->port.flags, info->isdn_driver, 1977 info->isdn_channel, dev->usage[idx]); 1978#endif 1979 if ( 1980#ifndef FIX_FILE_TRANSFER 1981 (info->port.flags & ASYNC_NORMAL_ACTIVE) && 1982#endif 1983 (info->isdn_driver == -1) && 1984 (info->isdn_channel == -1) && 1985 (USG_NONE(dev->usage[idx]))) { 1986 int matchret; 1987 1988 if ((matchret = isdn_tty_match_icall(eaz, &info->emu, di)) > wret) 1989 wret = matchret; 1990 if (!matchret) { /* EAZ is matching */ 1991 info->isdn_driver = di; 1992 info->isdn_channel = ch; 1993 info->drv_index = idx; 1994 dev->m_idx[idx] = info->line; 1995 dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE; 1996 dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]); 1997 strcpy(dev->num[idx], nr); 1998 strcpy(info->emu.cpn, eaz); 1999 info->emu.mdmreg[REG_SI1I] = si2bit[si1]; 2000 info->emu.mdmreg[REG_PLAN] = setup->plan; 2001 info->emu.mdmreg[REG_SCREEN] = setup->screen; 2002 isdn_info_update(); 2003 spin_unlock_irqrestore(&dev->lock, flags); 2004 printk(KERN_INFO "isdn_tty: call from %s, -> RING on ttyI%d\n", nr, 2005 info->line); 2006 info->msr |= UART_MSR_RI; 2007 isdn_tty_modem_result(RESULT_RING, info); 2008 isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1); 2009 return 1; 2010 } 2011 } 2012 } 2013 } 2014 spin_unlock_irqrestore(&dev->lock, flags); 2015 printk(KERN_INFO "isdn_tty: call from %s -> %s %s\n", nr, eaz, 2016 ((dev->drv[di]->flags & DRV_FLAG_REJBUS) && (wret != 2)) ? "rejected" : "ignored"); 2017 return (wret == 2) ? 3 : 0; 2018} 2019 2020#define TTY_IS_ACTIVE(info) (info->port.flags & ASYNC_NORMAL_ACTIVE) 2021 2022int 2023isdn_tty_stat_callback(int i, isdn_ctrl *c) 2024{ 2025 int mi; 2026 modem_info *info; 2027 char *e; 2028 2029 if (i < 0) 2030 return 0; 2031 if ((mi = dev->m_idx[i]) >= 0) { 2032 info = &dev->mdm.info[mi]; 2033 switch (c->command) { 2034 case ISDN_STAT_CINF: 2035 printk(KERN_DEBUG "CHARGEINFO on ttyI%d: %ld %s\n", info->line, c->arg, c->parm.num); 2036 info->emu.charge = (unsigned) simple_strtoul(c->parm.num, &e, 10); 2037 if (e == (char *)c->parm.num) 2038 info->emu.charge = 0; 2039 2040 break; 2041 case ISDN_STAT_BSENT: 2042#ifdef ISDN_TTY_STAT_DEBUG 2043 printk(KERN_DEBUG "tty_STAT_BSENT ttyI%d\n", info->line); 2044#endif 2045 if ((info->isdn_driver == c->driver) && 2046 (info->isdn_channel == c->arg)) { 2047 info->msr |= UART_MSR_CTS; 2048 if (info->send_outstanding) 2049 if (!(--info->send_outstanding)) 2050 info->lsr |= UART_LSR_TEMT; 2051 isdn_tty_tint(info); 2052 return 1; 2053 } 2054 break; 2055 case ISDN_STAT_CAUSE: 2056#ifdef ISDN_TTY_STAT_DEBUG 2057 printk(KERN_DEBUG "tty_STAT_CAUSE ttyI%d\n", info->line); 2058#endif 2059 /* Signal cause to tty-device */ 2060 strncpy(info->last_cause, c->parm.num, 5); 2061 return 1; 2062 case ISDN_STAT_DISPLAY: 2063#ifdef ISDN_TTY_STAT_DEBUG 2064 printk(KERN_DEBUG "tty_STAT_DISPLAY ttyI%d\n", info->line); 2065#endif 2066 /* Signal display to tty-device */ 2067 if ((info->emu.mdmreg[REG_DISPLAY] & BIT_DISPLAY) && 2068 !(info->emu.mdmreg[REG_RESPNUM] & BIT_RESPNUM)) { 2069 isdn_tty_at_cout("\r\n", info); 2070 isdn_tty_at_cout("DISPLAY: ", info); 2071 isdn_tty_at_cout(c->parm.display, info); 2072 isdn_tty_at_cout("\r\n", info); 2073 } 2074 return 1; 2075 case ISDN_STAT_DCONN: 2076#ifdef ISDN_TTY_STAT_DEBUG 2077 printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line); 2078#endif 2079 if (TTY_IS_ACTIVE(info)) { 2080 if (info->dialing == 1) { 2081 info->dialing = 2; 2082 return 1; 2083 } 2084 } 2085 break; 2086 case ISDN_STAT_DHUP: 2087#ifdef ISDN_TTY_STAT_DEBUG 2088 printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line); 2089#endif 2090 if (TTY_IS_ACTIVE(info)) { 2091 if (info->dialing == 1) 2092 isdn_tty_modem_result(RESULT_BUSY, info); 2093 if (info->dialing > 1) 2094 isdn_tty_modem_result(RESULT_NO_CARRIER, info); 2095 info->dialing = 0; 2096#ifdef ISDN_DEBUG_MODEM_HUP 2097 printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n"); 2098#endif 2099 isdn_tty_modem_hup(info, 0); 2100 return 1; 2101 } 2102 break; 2103 case ISDN_STAT_BCONN: 2104#ifdef ISDN_TTY_STAT_DEBUG 2105 printk(KERN_DEBUG "tty_STAT_BCONN ttyI%d\n", info->line); 2106#endif 2107 /* Wake up any processes waiting 2108 * for incoming call of this device when 2109 * DCD follow the state of incoming carrier 2110 */ 2111 if (info->port.blocked_open && 2112 (info->emu.mdmreg[REG_DCD] & BIT_DCD)) { 2113 wake_up_interruptible(&info->port.open_wait); 2114 } 2115 2116 /* Schedule CONNECT-Message to any tty 2117 * waiting for it and 2118 * set DCD-bit of its modem-status. 2119 */ 2120 if (TTY_IS_ACTIVE(info) || 2121 (info->port.blocked_open && 2122 (info->emu.mdmreg[REG_DCD] & BIT_DCD))) { 2123 info->msr |= UART_MSR_DCD; 2124 info->emu.charge = 0; 2125 if (info->dialing & 0xf) 2126 info->last_dir = 1; 2127 else 2128 info->last_dir = 0; 2129 info->dialing = 0; 2130 info->rcvsched = 1; 2131 if (USG_MODEM(dev->usage[i])) { 2132 if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) { 2133 strcpy(info->emu.connmsg, c->parm.num); 2134 isdn_tty_modem_result(RESULT_CONNECT, info); 2135 } else 2136 isdn_tty_modem_result(RESULT_CONNECT64000, info); 2137 } 2138 if (USG_VOICE(dev->usage[i])) 2139 isdn_tty_modem_result(RESULT_VCON, info); 2140 return 1; 2141 } 2142 break; 2143 case ISDN_STAT_BHUP: 2144#ifdef ISDN_TTY_STAT_DEBUG 2145 printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line); 2146#endif 2147 if (TTY_IS_ACTIVE(info)) { 2148#ifdef ISDN_DEBUG_MODEM_HUP 2149 printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n"); 2150#endif 2151 isdn_tty_modem_hup(info, 0); 2152 return 1; 2153 } 2154 break; 2155 case ISDN_STAT_NODCH: 2156#ifdef ISDN_TTY_STAT_DEBUG 2157 printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line); 2158#endif 2159 if (TTY_IS_ACTIVE(info)) { 2160 if (info->dialing) { 2161 info->dialing = 0; 2162 info->last_l2 = -1; 2163 info->last_si = 0; 2164 sprintf(info->last_cause, "0000"); 2165 isdn_tty_modem_result(RESULT_NO_DIALTONE, info); 2166 } 2167 isdn_tty_modem_hup(info, 0); 2168 return 1; 2169 } 2170 break; 2171 case ISDN_STAT_UNLOAD: 2172#ifdef ISDN_TTY_STAT_DEBUG 2173 printk(KERN_DEBUG "tty_STAT_UNLOAD ttyI%d\n", info->line); 2174#endif 2175 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 2176 info = &dev->mdm.info[i]; 2177 if (info->isdn_driver == c->driver) { 2178 if (info->online) 2179 isdn_tty_modem_hup(info, 1); 2180 } 2181 } 2182 return 1; 2183#ifdef CONFIG_ISDN_TTY_FAX 2184 case ISDN_STAT_FAXIND: 2185 if (TTY_IS_ACTIVE(info)) { 2186 isdn_tty_fax_command(info, c); 2187 } 2188 break; 2189#endif 2190#ifdef CONFIG_ISDN_AUDIO 2191 case ISDN_STAT_AUDIO: 2192 if (TTY_IS_ACTIVE(info)) { 2193 switch (c->parm.num[0]) { 2194 case ISDN_AUDIO_DTMF: 2195 if (info->vonline) { 2196 isdn_audio_put_dle_code(info, 2197 c->parm.num[1]); 2198 } 2199 break; 2200 } 2201 } 2202 break; 2203#endif 2204 } 2205 } 2206 return 0; 2207} 2208 2209/********************************************************************* 2210 Modem-Emulator-Routines 2211*********************************************************************/ 2212 2213#define cmdchar(c) ((c >= ' ') && (c <= 0x7f)) 2214 2215/* 2216 * Put a message from the AT-emulator into receive-buffer of tty, 2217 * convert CR, LF, and BS to values in modem-registers 3, 4 and 5. 2218 */ 2219void 2220isdn_tty_at_cout(char *msg, modem_info *info) 2221{ 2222 struct tty_port *port = &info->port; 2223 atemu *m = &info->emu; 2224 char *p; 2225 char c; 2226 u_long flags; 2227 struct sk_buff *skb = NULL; 2228 char *sp = NULL; 2229 int l; 2230 2231 if (!msg) { 2232 printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); 2233 return; 2234 } 2235 2236 l = strlen(msg); 2237 2238 spin_lock_irqsave(&info->readlock, flags); 2239 if (port->flags & ASYNC_CLOSING) { 2240 spin_unlock_irqrestore(&info->readlock, flags); 2241 return; 2242 } 2243 2244 /* use queue instead of direct, if online and */ 2245 /* data is in queue or buffer is full */ 2246 if (info->online && ((tty_buffer_request_room(port, l) < l) || 2247 !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { 2248 skb = alloc_skb(l, GFP_ATOMIC); 2249 if (!skb) { 2250 spin_unlock_irqrestore(&info->readlock, flags); 2251 return; 2252 } 2253 sp = skb_put(skb, l); 2254#ifdef CONFIG_ISDN_AUDIO 2255 ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; 2256 ISDN_AUDIO_SKB_LOCK(skb) = 0; 2257#endif 2258 } 2259 2260 for (p = msg; *p; p++) { 2261 switch (*p) { 2262 case '\r': 2263 c = m->mdmreg[REG_CR]; 2264 break; 2265 case '\n': 2266 c = m->mdmreg[REG_LF]; 2267 break; 2268 case '\b': 2269 c = m->mdmreg[REG_BS]; 2270 break; 2271 default: 2272 c = *p; 2273 } 2274 if (skb) { 2275 *sp++ = c; 2276 } else { 2277 if (tty_insert_flip_char(port, c, TTY_NORMAL) == 0) 2278 break; 2279 } 2280 } 2281 if (skb) { 2282 __skb_queue_tail(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel], skb); 2283 dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; 2284 spin_unlock_irqrestore(&info->readlock, flags); 2285 /* Schedule dequeuing */ 2286 if (dev->modempoll && info->rcvsched) 2287 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); 2288 2289 } else { 2290 spin_unlock_irqrestore(&info->readlock, flags); 2291 tty_flip_buffer_push(port); 2292 } 2293} 2294 2295/* 2296 * Perform ATH Hangup 2297 */ 2298static void 2299isdn_tty_on_hook(modem_info *info) 2300{ 2301 if (info->isdn_channel >= 0) { 2302#ifdef ISDN_DEBUG_MODEM_HUP 2303 printk(KERN_DEBUG "Mhup in isdn_tty_on_hook\n"); 2304#endif 2305 isdn_tty_modem_hup(info, 1); 2306 } 2307} 2308 2309static void 2310isdn_tty_off_hook(void) 2311{ 2312 printk(KERN_DEBUG "isdn_tty_off_hook\n"); 2313} 2314 2315#define PLUSWAIT1 (HZ / 2) /* 0.5 sec. */ 2316#define PLUSWAIT2 (HZ * 3 / 2) /* 1.5 sec */ 2317 2318/* 2319 * Check Buffer for Modem-escape-sequence, activate timer-callback to 2320 * isdn_tty_modem_escape() if sequence found. 2321 * 2322 * Parameters: 2323 * p pointer to databuffer 2324 * plus escape-character 2325 * count length of buffer 2326 * pluscount count of valid escape-characters so far 2327 * lastplus timestamp of last character 2328 */ 2329static void 2330isdn_tty_check_esc(const u_char *p, u_char plus, int count, int *pluscount, 2331 u_long *lastplus) 2332{ 2333 if (plus > 127) 2334 return; 2335 if (count > 3) { 2336 p += count - 3; 2337 count = 3; 2338 *pluscount = 0; 2339 } 2340 while (count > 0) { 2341 if (*(p++) == plus) { 2342 if ((*pluscount)++) { 2343 /* Time since last '+' > 0.5 sec. ? */ 2344 if (time_after(jiffies, *lastplus + PLUSWAIT1)) 2345 *pluscount = 1; 2346 } else { 2347 /* Time since last non-'+' < 1.5 sec. ? */ 2348 if (time_before(jiffies, *lastplus + PLUSWAIT2)) 2349 *pluscount = 0; 2350 } 2351 if ((*pluscount == 3) && (count == 1)) 2352 isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, 1); 2353 if (*pluscount > 3) 2354 *pluscount = 1; 2355 } else 2356 *pluscount = 0; 2357 *lastplus = jiffies; 2358 count--; 2359 } 2360} 2361 2362/* 2363 * Return result of AT-emulator to tty-receive-buffer, depending on 2364 * modem-register 12, bit 0 and 1. 2365 * For CONNECT-messages also switch to online-mode. 2366 * For RING-message handle auto-ATA if register 0 != 0 2367 */ 2368 2369static void 2370isdn_tty_modem_result(int code, modem_info *info) 2371{ 2372 atemu *m = &info->emu; 2373 static char *msg[] = 2374 {"OK", "CONNECT", "RING", "NO CARRIER", "ERROR", 2375 "CONNECT 64000", "NO DIALTONE", "BUSY", "NO ANSWER", 2376 "RINGING", "NO MSN/EAZ", "VCON", "RUNG"}; 2377 char s[ISDN_MSNLEN + 10]; 2378 2379 switch (code) { 2380 case RESULT_RING: 2381 m->mdmreg[REG_RINGCNT]++; 2382 if (m->mdmreg[REG_RINGCNT] == m->mdmreg[REG_RINGATA]) 2383 /* Automatically accept incoming call */ 2384 isdn_tty_cmd_ATA(info); 2385 break; 2386 case RESULT_NO_CARRIER: 2387#ifdef ISDN_DEBUG_MODEM_HUP 2388 printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n", 2389 (info->port.flags & ASYNC_CLOSING), 2390 (!info->port.tty)); 2391#endif 2392 m->mdmreg[REG_RINGCNT] = 0; 2393 del_timer(&info->nc_timer); 2394 info->ncarrier = 0; 2395 if ((info->port.flags & ASYNC_CLOSING) || (!info->port.tty)) 2396 return; 2397 2398#ifdef CONFIG_ISDN_AUDIO 2399 if (info->vonline & 1) { 2400#ifdef ISDN_DEBUG_MODEM_VOICE 2401 printk(KERN_DEBUG "res3: send DLE-ETX on ttyI%d\n", 2402 info->line); 2403#endif 2404 /* voice-recording, add DLE-ETX */ 2405 isdn_tty_at_cout("\020\003", info); 2406 } 2407 if (info->vonline & 2) { 2408#ifdef ISDN_DEBUG_MODEM_VOICE 2409 printk(KERN_DEBUG "res3: send DLE-DC4 on ttyI%d\n", 2410 info->line); 2411#endif 2412 /* voice-playing, add DLE-DC4 */ 2413 isdn_tty_at_cout("\020\024", info); 2414 } 2415#endif 2416 break; 2417 case RESULT_CONNECT: 2418 case RESULT_CONNECT64000: 2419 sprintf(info->last_cause, "0000"); 2420 if (!info->online) 2421 info->online = 2; 2422 break; 2423 case RESULT_VCON: 2424#ifdef ISDN_DEBUG_MODEM_VOICE 2425 printk(KERN_DEBUG "res3: send VCON on ttyI%d\n", 2426 info->line); 2427#endif 2428 sprintf(info->last_cause, "0000"); 2429 if (!info->online) 2430 info->online = 1; 2431 break; 2432 } /* switch (code) */ 2433 2434 if (m->mdmreg[REG_RESP] & BIT_RESP) { 2435 /* Show results */ 2436 if (m->mdmreg[REG_RESPNUM] & BIT_RESPNUM) { 2437 /* Show numeric results only */ 2438 sprintf(s, "\r\n%d\r\n", code); 2439 isdn_tty_at_cout(s, info); 2440 } else { 2441 if (code == RESULT_RING) { 2442 /* return if "show RUNG" and ringcounter>1 */ 2443 if ((m->mdmreg[REG_RUNG] & BIT_RUNG) && 2444 (m->mdmreg[REG_RINGCNT] > 1)) 2445 return; 2446 /* print CID, _before_ _every_ ring */ 2447 if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) { 2448 isdn_tty_at_cout("\r\nCALLER NUMBER: ", info); 2449 isdn_tty_at_cout(dev->num[info->drv_index], info); 2450 if (m->mdmreg[REG_CDN] & BIT_CDN) { 2451 isdn_tty_at_cout("\r\nCALLED NUMBER: ", info); 2452 isdn_tty_at_cout(info->emu.cpn, info); 2453 } 2454 } 2455 } 2456 isdn_tty_at_cout("\r\n", info); 2457 isdn_tty_at_cout(msg[code], info); 2458 switch (code) { 2459 case RESULT_CONNECT: 2460 switch (m->mdmreg[REG_L2PROT]) { 2461 case ISDN_PROTO_L2_MODEM: 2462 isdn_tty_at_cout(" ", info); 2463 isdn_tty_at_cout(m->connmsg, info); 2464 break; 2465 } 2466 break; 2467 case RESULT_RING: 2468 /* Append CPN, if enabled */ 2469 if ((m->mdmreg[REG_CPN] & BIT_CPN)) { 2470 sprintf(s, "/%s", m->cpn); 2471 isdn_tty_at_cout(s, info); 2472 } 2473 /* Print CID only once, _after_ 1st RING */ 2474 if ((m->mdmreg[REG_CIDONCE] & BIT_CIDONCE) && 2475 (m->mdmreg[REG_RINGCNT] == 1)) { 2476 isdn_tty_at_cout("\r\n", info); 2477 isdn_tty_at_cout("CALLER NUMBER: ", info); 2478 isdn_tty_at_cout(dev->num[info->drv_index], info); 2479 if (m->mdmreg[REG_CDN] & BIT_CDN) { 2480 isdn_tty_at_cout("\r\nCALLED NUMBER: ", info); 2481 isdn_tty_at_cout(info->emu.cpn, info); 2482 } 2483 } 2484 break; 2485 case RESULT_NO_CARRIER: 2486 case RESULT_NO_DIALTONE: 2487 case RESULT_BUSY: 2488 case RESULT_NO_ANSWER: 2489 m->mdmreg[REG_RINGCNT] = 0; 2490 /* Append Cause-Message if enabled */ 2491 if (m->mdmreg[REG_RESPXT] & BIT_RESPXT) { 2492 sprintf(s, "/%s", info->last_cause); 2493 isdn_tty_at_cout(s, info); 2494 } 2495 break; 2496 case RESULT_CONNECT64000: 2497 /* Append Protocol to CONNECT message */ 2498 switch (m->mdmreg[REG_L2PROT]) { 2499 case ISDN_PROTO_L2_X75I: 2500 case ISDN_PROTO_L2_X75UI: 2501 case ISDN_PROTO_L2_X75BUI: 2502 isdn_tty_at_cout("/X.75", info); 2503 break; 2504 case ISDN_PROTO_L2_HDLC: 2505 isdn_tty_at_cout("/HDLC", info); 2506 break; 2507 case ISDN_PROTO_L2_V11096: 2508 isdn_tty_at_cout("/V110/9600", info); 2509 break; 2510 case ISDN_PROTO_L2_V11019: 2511 isdn_tty_at_cout("/V110/19200", info); 2512 break; 2513 case ISDN_PROTO_L2_V11038: 2514 isdn_tty_at_cout("/V110/38400", info); 2515 break; 2516 } 2517 if (m->mdmreg[REG_T70] & BIT_T70) { 2518 isdn_tty_at_cout("/T.70", info); 2519 if (m->mdmreg[REG_T70] & BIT_T70_EXT) 2520 isdn_tty_at_cout("+", info); 2521 } 2522 break; 2523 } 2524 isdn_tty_at_cout("\r\n", info); 2525 } 2526 } 2527 if (code == RESULT_NO_CARRIER) { 2528 if ((info->port.flags & ASYNC_CLOSING) || (!info->port.tty)) 2529 return; 2530 2531 if (info->port.flags & ASYNC_CHECK_CD) 2532 tty_hangup(info->port.tty); 2533 } 2534} 2535 2536 2537/* 2538 * Display a modem-register-value. 2539 */ 2540static void 2541isdn_tty_show_profile(int ridx, modem_info *info) 2542{ 2543 char v[6]; 2544 2545 sprintf(v, "\r\n%d", info->emu.mdmreg[ridx]); 2546 isdn_tty_at_cout(v, info); 2547} 2548 2549/* 2550 * Get MSN-string from char-pointer, set pointer to end of number 2551 */ 2552static void 2553isdn_tty_get_msnstr(char *n, char **p) 2554{ 2555 int limit = ISDN_MSNLEN - 1; 2556 2557 while (((*p[0] >= '0' && *p[0] <= '9') || 2558 /* Why a comma ??? */ 2559 (*p[0] == ',') || (*p[0] == ':')) && 2560 (limit--)) 2561 *n++ = *p[0]++; 2562 *n = '\0'; 2563} 2564 2565/* 2566 * Get phone-number from modem-commandbuffer 2567 */ 2568static void 2569isdn_tty_getdial(char *p, char *q, int cnt) 2570{ 2571 int first = 1; 2572 int limit = ISDN_MSNLEN - 1; /* MUST match the size of interface var to avoid 2573 buffer overflow */ 2574 2575 while (strchr(" 0123456789,#.*WPTSR-", *p) && *p && --cnt > 0) { 2576 if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) || 2577 ((*p == 'R') && first) || 2578 (*p == '*') || (*p == '#')) { 2579 *q++ = *p; 2580 limit--; 2581 } 2582 if (!limit) 2583 break; 2584 p++; 2585 first = 0; 2586 } 2587 *q = 0; 2588} 2589 2590#define PARSE_ERROR { isdn_tty_modem_result(RESULT_ERROR, info); return; } 2591#define PARSE_ERROR1 { isdn_tty_modem_result(RESULT_ERROR, info); return 1; } 2592 2593static void 2594isdn_tty_report(modem_info *info) 2595{ 2596 atemu *m = &info->emu; 2597 char s[80]; 2598 2599 isdn_tty_at_cout("\r\nStatistics of last connection:\r\n\r\n", info); 2600 sprintf(s, " Remote Number: %s\r\n", info->last_num); 2601 isdn_tty_at_cout(s, info); 2602 sprintf(s, " Direction: %s\r\n", info->last_dir ? "outgoing" : "incoming"); 2603 isdn_tty_at_cout(s, info); 2604 isdn_tty_at_cout(" Layer-2 Protocol: ", info); 2605 switch (info->last_l2) { 2606 case ISDN_PROTO_L2_X75I: 2607 isdn_tty_at_cout("X.75i", info); 2608 break; 2609 case ISDN_PROTO_L2_X75UI: 2610 isdn_tty_at_cout("X.75ui", info); 2611 break; 2612 case ISDN_PROTO_L2_X75BUI: 2613 isdn_tty_at_cout("X.75bui", info); 2614 break; 2615 case ISDN_PROTO_L2_HDLC: 2616 isdn_tty_at_cout("HDLC", info); 2617 break; 2618 case ISDN_PROTO_L2_V11096: 2619 isdn_tty_at_cout("V.110 9600 Baud", info); 2620 break; 2621 case ISDN_PROTO_L2_V11019: 2622 isdn_tty_at_cout("V.110 19200 Baud", info); 2623 break; 2624 case ISDN_PROTO_L2_V11038: 2625 isdn_tty_at_cout("V.110 38400 Baud", info); 2626 break; 2627 case ISDN_PROTO_L2_TRANS: 2628 isdn_tty_at_cout("transparent", info); 2629 break; 2630 case ISDN_PROTO_L2_MODEM: 2631 isdn_tty_at_cout("modem", info); 2632 break; 2633 case ISDN_PROTO_L2_FAX: 2634 isdn_tty_at_cout("fax", info); 2635 break; 2636 default: 2637 isdn_tty_at_cout("unknown", info); 2638 break; 2639 } 2640 if (m->mdmreg[REG_T70] & BIT_T70) { 2641 isdn_tty_at_cout("/T.70", info); 2642 if (m->mdmreg[REG_T70] & BIT_T70_EXT) 2643 isdn_tty_at_cout("+", info); 2644 } 2645 isdn_tty_at_cout("\r\n", info); 2646 isdn_tty_at_cout(" Service: ", info); 2647 switch (info->last_si) { 2648 case 1: 2649 isdn_tty_at_cout("audio\r\n", info); 2650 break; 2651 case 5: 2652 isdn_tty_at_cout("btx\r\n", info); 2653 break; 2654 case 7: 2655 isdn_tty_at_cout("data\r\n", info); 2656 break; 2657 default: 2658 sprintf(s, "%d\r\n", info->last_si); 2659 isdn_tty_at_cout(s, info); 2660 break; 2661 } 2662 sprintf(s, " Hangup location: %s\r\n", info->last_lhup ? "local" : "remote"); 2663 isdn_tty_at_cout(s, info); 2664 sprintf(s, " Last cause: %s\r\n", info->last_cause); 2665 isdn_tty_at_cout(s, info); 2666} 2667 2668/* 2669 * Parse AT&.. commands. 2670 */ 2671static int 2672isdn_tty_cmd_ATand(char **p, modem_info *info) 2673{ 2674 atemu *m = &info->emu; 2675 int i; 2676 char rb[100]; 2677 2678#define MAXRB (sizeof(rb) - 1) 2679 2680 switch (*p[0]) { 2681 case 'B': 2682 /* &B - Set Buffersize */ 2683 p[0]++; 2684 i = isdn_getnum(p); 2685 if ((i < 0) || (i > ISDN_SERIAL_XMIT_MAX)) 2686 PARSE_ERROR1; 2687#ifdef CONFIG_ISDN_AUDIO 2688 if ((m->mdmreg[REG_SI1] & 1) && (i > VBUF)) 2689 PARSE_ERROR1; 2690#endif 2691 m->mdmreg[REG_PSIZE] = i / 16; 2692 info->xmit_size = m->mdmreg[REG_PSIZE] * 16; 2693 switch (m->mdmreg[REG_L2PROT]) { 2694 case ISDN_PROTO_L2_V11096: 2695 case ISDN_PROTO_L2_V11019: 2696 case ISDN_PROTO_L2_V11038: 2697 info->xmit_size /= 10; 2698 } 2699 break; 2700 case 'C': 2701 /* &C - DCD Status */ 2702 p[0]++; 2703 switch (isdn_getnum(p)) { 2704 case 0: 2705 m->mdmreg[REG_DCD] &= ~BIT_DCD; 2706 break; 2707 case 1: 2708 m->mdmreg[REG_DCD] |= BIT_DCD; 2709 break; 2710 default: 2711 PARSE_ERROR1 2712 } 2713 break; 2714 case 'D': 2715 /* &D - Set DTR-Low-behavior */ 2716 p[0]++; 2717 switch (isdn_getnum(p)) { 2718 case 0: 2719 m->mdmreg[REG_DTRHUP] &= ~BIT_DTRHUP; 2720 m->mdmreg[REG_DTRR] &= ~BIT_DTRR; 2721 break; 2722 case 2: 2723 m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP; 2724 m->mdmreg[REG_DTRR] &= ~BIT_DTRR; 2725 break; 2726 case 3: 2727 m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP; 2728 m->mdmreg[REG_DTRR] |= BIT_DTRR; 2729 break; 2730 default: 2731 PARSE_ERROR1 2732 } 2733 break; 2734 case 'E': 2735 /* &E -Set EAZ/MSN */ 2736 p[0]++; 2737 isdn_tty_get_msnstr(m->msn, p); 2738 break; 2739 case 'F': 2740 /* &F -Set Factory-Defaults */ 2741 p[0]++; 2742 if (info->msr & UART_MSR_DCD) 2743 PARSE_ERROR1; 2744 isdn_tty_reset_profile(m); 2745 isdn_tty_modem_reset_regs(info, 1); 2746 break; 2747#ifdef DUMMY_HAYES_AT 2748 case 'K': 2749 /* only for be compilant with common scripts */ 2750 /* &K Flowcontrol - no function */ 2751 p[0]++; 2752 isdn_getnum(p); 2753 break; 2754#endif 2755 case 'L': 2756 /* &L -Set Numbers to listen on */ 2757 p[0]++; 2758 i = 0; 2759 while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) && 2760 (i < ISDN_LMSNLEN - 1)) 2761 m->lmsn[i++] = *p[0]++; 2762 m->lmsn[i] = '\0'; 2763 break; 2764 case 'R': 2765 /* &R - Set V.110 bitrate adaption */ 2766 p[0]++; 2767 i = isdn_getnum(p); 2768 switch (i) { 2769 case 0: 2770 /* Switch off V.110, back to X.75 */ 2771 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I; 2772 m->mdmreg[REG_SI2] = 0; 2773 info->xmit_size = m->mdmreg[REG_PSIZE] * 16; 2774 break; 2775 case 9600: 2776 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11096; 2777 m->mdmreg[REG_SI2] = 197; 2778 info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10; 2779 break; 2780 case 19200: 2781 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11019; 2782 m->mdmreg[REG_SI2] = 199; 2783 info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10; 2784 break; 2785 case 38400: 2786 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11038; 2787 m->mdmreg[REG_SI2] = 198; /* no existing standard for this */ 2788 info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10; 2789 break; 2790 default: 2791 PARSE_ERROR1; 2792 } 2793 /* Switch off T.70 */ 2794 m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT); 2795 /* Set Service 7 */ 2796 m->mdmreg[REG_SI1] |= 4; 2797 break; 2798 case 'S': 2799 /* &S - Set Windowsize */ 2800 p[0]++; 2801 i = isdn_getnum(p); 2802 if ((i > 0) && (i < 9)) 2803 m->mdmreg[REG_WSIZE] = i; 2804 else 2805 PARSE_ERROR1; 2806 break; 2807 case 'V': 2808 /* &V - Show registers */ 2809 p[0]++; 2810 isdn_tty_at_cout("\r\n", info); 2811 for (i = 0; i < ISDN_MODEM_NUMREG; i++) { 2812 sprintf(rb, "S%02d=%03d%s", i, 2813 m->mdmreg[i], ((i + 1) % 10) ? " " : "\r\n"); 2814 isdn_tty_at_cout(rb, info); 2815 } 2816 sprintf(rb, "\r\nEAZ/MSN: %.50s\r\n", 2817 strlen(m->msn) ? m->msn : "None"); 2818 isdn_tty_at_cout(rb, info); 2819 if (strlen(m->lmsn)) { 2820 isdn_tty_at_cout("\r\nListen: ", info); 2821 isdn_tty_at_cout(m->lmsn, info); 2822 isdn_tty_at_cout("\r\n", info); 2823 } 2824 break; 2825 case 'W': 2826 /* &W - Write Profile */ 2827 p[0]++; 2828 switch (*p[0]) { 2829 case '0': 2830 p[0]++; 2831 modem_write_profile(m); 2832 break; 2833 default: 2834 PARSE_ERROR1; 2835 } 2836 break; 2837 case 'X': 2838 /* &X - Switch to BTX-Mode and T.70 */ 2839 p[0]++; 2840 switch (isdn_getnum(p)) { 2841 case 0: 2842 m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT); 2843 info->xmit_size = m->mdmreg[REG_PSIZE] * 16; 2844 break; 2845 case 1: 2846 m->mdmreg[REG_T70] |= BIT_T70; 2847 m->mdmreg[REG_T70] &= ~BIT_T70_EXT; 2848 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I; 2849 info->xmit_size = 112; 2850 m->mdmreg[REG_SI1] = 4; 2851 m->mdmreg[REG_SI2] = 0; 2852 break; 2853 case 2: 2854 m->mdmreg[REG_T70] |= (BIT_T70 | BIT_T70_EXT); 2855 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I; 2856 info->xmit_size = 112; 2857 m->mdmreg[REG_SI1] = 4; 2858 m->mdmreg[REG_SI2] = 0; 2859 break; 2860 default: 2861 PARSE_ERROR1; 2862 } 2863 break; 2864 default: 2865 PARSE_ERROR1; 2866 } 2867 return 0; 2868} 2869 2870static int 2871isdn_tty_check_ats(int mreg, int mval, modem_info *info, atemu *m) 2872{ 2873 /* Some plausibility checks */ 2874 switch (mreg) { 2875 case REG_L2PROT: 2876 if (mval > ISDN_PROTO_L2_MAX) 2877 return 1; 2878 break; 2879 case REG_PSIZE: 2880 if ((mval * 16) > ISDN_SERIAL_XMIT_MAX) 2881 return 1; 2882#ifdef CONFIG_ISDN_AUDIO 2883 if ((m->mdmreg[REG_SI1] & 1) && (mval > VBUFX)) 2884 return 1; 2885#endif 2886 info->xmit_size = mval * 16; 2887 switch (m->mdmreg[REG_L2PROT]) { 2888 case ISDN_PROTO_L2_V11096: 2889 case ISDN_PROTO_L2_V11019: 2890 case ISDN_PROTO_L2_V11038: 2891 info->xmit_size /= 10; 2892 } 2893 break; 2894 case REG_SI1I: 2895 case REG_PLAN: 2896 case REG_SCREEN: 2897 /* readonly registers */ 2898 return 1; 2899 } 2900 return 0; 2901} 2902 2903/* 2904 * Perform ATS command 2905 */ 2906static int 2907isdn_tty_cmd_ATS(char **p, modem_info *info) 2908{ 2909 atemu *m = &info->emu; 2910 int bitpos; 2911 int mreg; 2912 int mval; 2913 int bval; 2914 2915 mreg = isdn_getnum(p); 2916 if (mreg < 0 || mreg >= ISDN_MODEM_NUMREG) 2917 PARSE_ERROR1; 2918 switch (*p[0]) { 2919 case '=': 2920 p[0]++; 2921 mval = isdn_getnum(p); 2922 if (mval < 0 || mval > 255) 2923 PARSE_ERROR1; 2924 if (isdn_tty_check_ats(mreg, mval, info, m)) 2925 PARSE_ERROR1; 2926 m->mdmreg[mreg] = mval; 2927 break; 2928 case '.': 2929 /* Set/Clear a single bit */ 2930 p[0]++; 2931 bitpos = isdn_getnum(p); 2932 if ((bitpos < 0) || (bitpos > 7)) 2933 PARSE_ERROR1; 2934 switch (*p[0]) { 2935 case '=': 2936 p[0]++; 2937 bval = isdn_getnum(p); 2938 if (bval < 0 || bval > 1) 2939 PARSE_ERROR1; 2940 if (bval) 2941 mval = m->mdmreg[mreg] | (1 << bitpos); 2942 else 2943 mval = m->mdmreg[mreg] & ~(1 << bitpos); 2944 if (isdn_tty_check_ats(mreg, mval, info, m)) 2945 PARSE_ERROR1; 2946 m->mdmreg[mreg] = mval; 2947 break; 2948 case '?': 2949 p[0]++; 2950 isdn_tty_at_cout("\r\n", info); 2951 isdn_tty_at_cout((m->mdmreg[mreg] & (1 << bitpos)) ? "1" : "0", 2952 info); 2953 break; 2954 default: 2955 PARSE_ERROR1; 2956 } 2957 break; 2958 case '?': 2959 p[0]++; 2960 isdn_tty_show_profile(mreg, info); 2961 break; 2962 default: 2963 PARSE_ERROR1; 2964 break; 2965 } 2966 return 0; 2967} 2968 2969/* 2970 * Perform ATA command 2971 */ 2972static void 2973isdn_tty_cmd_ATA(modem_info *info) 2974{ 2975 atemu *m = &info->emu; 2976 isdn_ctrl cmd; 2977 int l2; 2978 2979 if (info->msr & UART_MSR_RI) { 2980 /* Accept incoming call */ 2981 info->last_dir = 0; 2982 strcpy(info->last_num, dev->num[info->drv_index]); 2983 m->mdmreg[REG_RINGCNT] = 0; 2984 info->msr &= ~UART_MSR_RI; 2985 l2 = m->mdmreg[REG_L2PROT]; 2986#ifdef CONFIG_ISDN_AUDIO 2987 /* If more than one bit set in reg18, autoselect Layer2 */ 2988 if ((m->mdmreg[REG_SI1] & m->mdmreg[REG_SI1I]) != m->mdmreg[REG_SI1]) { 2989 if (m->mdmreg[REG_SI1I] == 1) { 2990 if ((l2 != ISDN_PROTO_L2_MODEM) && (l2 != ISDN_PROTO_L2_FAX)) 2991 l2 = ISDN_PROTO_L2_TRANS; 2992 } else 2993 l2 = ISDN_PROTO_L2_X75I; 2994 } 2995#endif 2996 cmd.driver = info->isdn_driver; 2997 cmd.command = ISDN_CMD_SETL2; 2998 cmd.arg = info->isdn_channel + (l2 << 8); 2999 info->last_l2 = l2; 3000 isdn_command(&cmd); 3001 cmd.driver = info->isdn_driver; 3002 cmd.command = ISDN_CMD_SETL3; 3003 cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8); 3004#ifdef CONFIG_ISDN_TTY_FAX 3005 if (l2 == ISDN_PROTO_L2_FAX) { 3006 cmd.parm.fax = info->fax; 3007 info->fax->direction = ISDN_TTY_FAX_CONN_IN; 3008 } 3009#endif 3010 isdn_command(&cmd); 3011 cmd.driver = info->isdn_driver; 3012 cmd.arg = info->isdn_channel; 3013 cmd.command = ISDN_CMD_ACCEPTD; 3014 info->dialing = 16; 3015 info->emu.carrierwait = 0; 3016 isdn_command(&cmd); 3017 isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1); 3018 } else 3019 isdn_tty_modem_result(RESULT_NO_ANSWER, info); 3020} 3021 3022#ifdef CONFIG_ISDN_AUDIO 3023/* 3024 * Parse AT+F.. commands 3025 */ 3026static int 3027isdn_tty_cmd_PLUSF(char **p, modem_info *info) 3028{ 3029 atemu *m = &info->emu; 3030 char rs[20]; 3031 3032 if (!strncmp(p[0], "CLASS", 5)) { 3033 p[0] += 5; 3034 switch (*p[0]) { 3035 case '?': 3036 p[0]++; 3037 sprintf(rs, "\r\n%d", 3038 (m->mdmreg[REG_SI1] & 1) ? 8 : 0); 3039#ifdef CONFIG_ISDN_TTY_FAX 3040 if (TTY_IS_FCLASS2(info)) 3041 sprintf(rs, "\r\n2"); 3042 else if (TTY_IS_FCLASS1(info)) 3043 sprintf(rs, "\r\n1"); 3044#endif 3045 isdn_tty_at_cout(rs, info); 3046 break; 3047 case '=': 3048 p[0]++; 3049 switch (*p[0]) { 3050 case '0': 3051 p[0]++; 3052 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I; 3053 m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS; 3054 m->mdmreg[REG_SI1] = 4; 3055 info->xmit_size = 3056 m->mdmreg[REG_PSIZE] * 16; 3057 break; 3058#ifdef CONFIG_ISDN_TTY_FAX 3059 case '1': 3060 p[0]++; 3061 if (!(dev->global_features & 3062 ISDN_FEATURE_L3_FCLASS1)) 3063 PARSE_ERROR1; 3064 m->mdmreg[REG_SI1] = 1; 3065 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX; 3066 m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS1; 3067 info->xmit_size = 3068 m->mdmreg[REG_PSIZE] * 16; 3069 break; 3070 case '2': 3071 p[0]++; 3072 if (!(dev->global_features & 3073 ISDN_FEATURE_L3_FCLASS2)) 3074 PARSE_ERROR1; 3075 m->mdmreg[REG_SI1] = 1; 3076 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX; 3077 m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS2; 3078 info->xmit_size = 3079 m->mdmreg[REG_PSIZE] * 16; 3080 break; 3081#endif 3082 case '8': 3083 p[0]++; 3084 /* L2 will change on dialout with si=1 */ 3085 m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I; 3086 m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS; 3087 m->mdmreg[REG_SI1] = 5; 3088 info->xmit_size = VBUF; 3089 break; 3090 case '?': 3091 p[0]++; 3092 strcpy(rs, "\r\n0,"); 3093#ifdef CONFIG_ISDN_TTY_FAX 3094 if (dev->global_features & 3095 ISDN_FEATURE_L3_FCLASS1) 3096 strcat(rs, "1,"); 3097 if (dev->global_features & 3098 ISDN_FEATURE_L3_FCLASS2) 3099 strcat(rs, "2,"); 3100#endif 3101 strcat(rs, "8"); 3102 isdn_tty_at_cout(rs, info); 3103 break; 3104 default: 3105 PARSE_ERROR1; 3106 } 3107 break; 3108 default: 3109 PARSE_ERROR1; 3110 } 3111 return 0; 3112 } 3113#ifdef CONFIG_ISDN_TTY_FAX 3114 return (isdn_tty_cmd_PLUSF_FAX(p, info)); 3115#else 3116 PARSE_ERROR1; 3117#endif 3118} 3119 3120/* 3121 * Parse AT+V.. commands 3122 */ 3123static int 3124isdn_tty_cmd_PLUSV(char **p, modem_info *info) 3125{ 3126 atemu *m = &info->emu; 3127 isdn_ctrl cmd; 3128 static char *vcmd[] = 3129 {"NH", "IP", "LS", "RX", "SD", "SM", "TX", "DD", NULL}; 3130 int i; 3131 int par1; 3132 int par2; 3133 char rs[20]; 3134 3135 i = 0; 3136 while (vcmd[i]) { 3137 if (!strncmp(vcmd[i], p[0], 2)) { 3138 p[0] += 2; 3139 break; 3140 } 3141 i++; 3142 } 3143 switch (i) { 3144 case 0: 3145 /* AT+VNH - Auto hangup feature */ 3146 switch (*p[0]) { 3147 case '?': 3148 p[0]++; 3149 isdn_tty_at_cout("\r\n1", info); 3150 break; 3151 case '=': 3152 p[0]++; 3153 switch (*p[0]) { 3154 case '1': 3155 p[0]++; 3156 break; 3157 case '?': 3158 p[0]++; 3159 isdn_tty_at_cout("\r\n1", info); 3160 break; 3161 default: 3162 PARSE_ERROR1; 3163 } 3164 break; 3165 default: 3166 PARSE_ERROR1; 3167 } 3168 break; 3169 case 1: 3170 /* AT+VIP - Reset all voice parameters */ 3171 isdn_tty_modem_reset_vpar(m); 3172 break; 3173 case 2: 3174 /* AT+VLS - Select device, accept incoming call */ 3175 switch (*p[0]) { 3176 case '?': 3177 p[0]++; 3178 sprintf(rs, "\r\n%d", m->vpar[0]); 3179 isdn_tty_at_cout(rs, info); 3180 break; 3181 case '=': 3182 p[0]++; 3183 switch (*p[0]) { 3184 case '0': 3185 p[0]++; 3186 m->vpar[0] = 0; 3187 break; 3188 case '2': 3189 p[0]++; 3190 m->vpar[0] = 2; 3191 break; 3192 case '?': 3193 p[0]++; 3194 isdn_tty_at_cout("\r\n0,2", info); 3195 break; 3196 default: 3197 PARSE_ERROR1; 3198 } 3199 break; 3200 default: 3201 PARSE_ERROR1; 3202 } 3203 break; 3204 case 3: 3205 /* AT+VRX - Start recording */ 3206 if (!m->vpar[0]) 3207 PARSE_ERROR1; 3208 if (info->online != 1) { 3209 isdn_tty_modem_result(RESULT_NO_ANSWER, info); 3210 return 1; 3211 } 3212 info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state); 3213 if (!info->dtmf_state) { 3214 printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n"); 3215 PARSE_ERROR1; 3216 } 3217 info->silence_state = isdn_audio_silence_init(info->silence_state); 3218 if (!info->silence_state) { 3219 printk(KERN_WARNING "isdn_tty: Couldn't malloc silence state\n"); 3220 PARSE_ERROR1; 3221 } 3222 if (m->vpar[3] < 5) { 3223 info->adpcmr = isdn_audio_adpcm_init(info->adpcmr, m->vpar[3]); 3224 if (!info->adpcmr) { 3225 printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n"); 3226 PARSE_ERROR1; 3227 } 3228 } 3229#ifdef ISDN_DEBUG_AT 3230 printk(KERN_DEBUG "AT: +VRX\n"); 3231#endif 3232 info->vonline |= 1; 3233 isdn_tty_modem_result(RESULT_CONNECT, info); 3234 return 0; 3235 break; 3236 case 4: 3237 /* AT+VSD - Silence detection */ 3238 switch (*p[0]) { 3239 case '?': 3240 p[0]++; 3241 sprintf(rs, "\r\n<%d>,<%d>", 3242 m->vpar[1], 3243 m->vpar[2]); 3244 isdn_tty_at_cout(rs, info); 3245 break; 3246 case '=': 3247 p[0]++; 3248 if ((*p[0] >= '0') && (*p[0] <= '9')) { 3249 par1 = isdn_getnum(p); 3250 if ((par1 < 0) || (par1 > 31)) 3251 PARSE_ERROR1; 3252 if (*p[0] != ',') 3253 PARSE_ERROR1; 3254 p[0]++; 3255 par2 = isdn_getnum(p); 3256 if ((par2 < 0) || (par2 > 255)) 3257 PARSE_ERROR1; 3258 m->vpar[1] = par1; 3259 m->vpar[2] = par2; 3260 break; 3261 } else 3262 if (*p[0] == '?') { 3263 p[0]++; 3264 isdn_tty_at_cout("\r\n<0-31>,<0-255>", 3265 info); 3266 break; 3267 } else 3268 PARSE_ERROR1; 3269 break; 3270 default: 3271 PARSE_ERROR1; 3272 } 3273 break; 3274 case 5: 3275 /* AT+VSM - Select compression */ 3276 switch (*p[0]) { 3277 case '?': 3278 p[0]++; 3279 sprintf(rs, "\r\n<%d>,<%d><8000>", 3280 m->vpar[3], 3281 m->vpar[1]); 3282 isdn_tty_at_cout(rs, info); 3283 break; 3284 case '=': 3285 p[0]++; 3286 switch (*p[0]) { 3287 case '2': 3288 case '3': 3289 case '4': 3290 case '5': 3291 case '6': 3292 par1 = isdn_getnum(p); 3293 if ((par1 < 2) || (par1 > 6)) 3294 PARSE_ERROR1; 3295 m->vpar[3] = par1; 3296 break; 3297 case '?': 3298 p[0]++; 3299 isdn_tty_at_cout("\r\n2;ADPCM;2;0;(8000)\r\n", 3300 info); 3301 isdn_tty_at_cout("3;ADPCM;3;0;(8000)\r\n", 3302 info); 3303 isdn_tty_at_cout("4;ADPCM;4;0;(8000)\r\n", 3304 info); 3305 isdn_tty_at_cout("5;ALAW;8;0;(8000)\r\n", 3306 info); 3307 isdn_tty_at_cout("6;ULAW;8;0;(8000)\r\n", 3308 info); 3309 break; 3310 default: 3311 PARSE_ERROR1; 3312 } 3313 break; 3314 default: 3315 PARSE_ERROR1; 3316 } 3317 break; 3318 case 6: 3319 /* AT+VTX - Start sending */ 3320 if (!m->vpar[0]) 3321 PARSE_ERROR1; 3322 if (info->online != 1) { 3323 isdn_tty_modem_result(RESULT_NO_ANSWER, info); 3324 return 1; 3325 } 3326 info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state); 3327 if (!info->dtmf_state) { 3328 printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n"); 3329 PARSE_ERROR1; 3330 } 3331 if (m->vpar[3] < 5) { 3332 info->adpcms = isdn_audio_adpcm_init(info->adpcms, m->vpar[3]); 3333 if (!info->adpcms) { 3334 printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n"); 3335 PARSE_ERROR1; 3336 } 3337 } 3338#ifdef ISDN_DEBUG_AT 3339 printk(KERN_DEBUG "AT: +VTX\n"); 3340#endif 3341 m->lastDLE = 0; 3342 info->vonline |= 2; 3343 isdn_tty_modem_result(RESULT_CONNECT, info); 3344 return 0; 3345 break; 3346 case 7: 3347 /* AT+VDD - DTMF detection */ 3348 switch (*p[0]) { 3349 case '?': 3350 p[0]++; 3351 sprintf(rs, "\r\n<%d>,<%d>", 3352 m->vpar[4], 3353 m->vpar[5]); 3354 isdn_tty_at_cout(rs, info); 3355 break; 3356 case '=': 3357 p[0]++; 3358 if ((*p[0] >= '0') && (*p[0] <= '9')) { 3359 if (info->online != 1) 3360 PARSE_ERROR1; 3361 par1 = isdn_getnum(p); 3362 if ((par1 < 0) || (par1 > 15)) 3363 PARSE_ERROR1; 3364 if (*p[0] != ',') 3365 PARSE_ERROR1; 3366 p[0]++; 3367 par2 = isdn_getnum(p); 3368 if ((par2 < 0) || (par2 > 255)) 3369 PARSE_ERROR1; 3370 m->vpar[4] = par1; 3371 m->vpar[5] = par2; 3372 cmd.driver = info->isdn_driver; 3373 cmd.command = ISDN_CMD_AUDIO; 3374 cmd.arg = info->isdn_channel + (ISDN_AUDIO_SETDD << 8); 3375 cmd.parm.num[0] = par1; 3376 cmd.parm.num[1] = par2; 3377 isdn_command(&cmd); 3378 break; 3379 } else 3380 if (*p[0] == '?') { 3381 p[0]++; 3382 isdn_tty_at_cout("\r\n<0-15>,<0-255>", 3383 info); 3384 break; 3385 } else 3386 PARSE_ERROR1; 3387 break; 3388 default: 3389 PARSE_ERROR1; 3390 } 3391 break; 3392 default: 3393 PARSE_ERROR1; 3394 } 3395 return 0; 3396} 3397#endif /* CONFIG_ISDN_AUDIO */ 3398 3399/* 3400 * Parse and perform an AT-command-line. 3401 */ 3402static void 3403isdn_tty_parse_at(modem_info *info) 3404{ 3405 atemu *m = &info->emu; 3406 char *p; 3407 char ds[ISDN_MSNLEN]; 3408 3409#ifdef ISDN_DEBUG_AT 3410 printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd); 3411#endif 3412 for (p = &m->mdmcmd[2]; *p;) { 3413 switch (*p) { 3414 case ' ': 3415 p++; 3416 break; 3417 case 'A': 3418 /* A - Accept incoming call */ 3419 p++; 3420 isdn_tty_cmd_ATA(info); 3421 return; 3422 case 'D': 3423 /* D - Dial */ 3424 if (info->msr & UART_MSR_DCD) 3425 PARSE_ERROR; 3426 if (info->msr & UART_MSR_RI) { 3427 isdn_tty_modem_result(RESULT_NO_CARRIER, info); 3428 return; 3429 } 3430 isdn_tty_getdial(++p, ds, sizeof ds); 3431 p += strlen(p); 3432 if (!strlen(m->msn)) 3433 isdn_tty_modem_result(RESULT_NO_MSN_EAZ, info); 3434 else if (strlen(ds)) 3435 isdn_tty_dial(ds, info, m); 3436 else 3437 PARSE_ERROR; 3438 return; 3439 case 'E': 3440 /* E - Turn Echo on/off */ 3441 p++; 3442 switch (isdn_getnum(&p)) { 3443 case 0: 3444 m->mdmreg[REG_ECHO] &= ~BIT_ECHO; 3445 break; 3446 case 1: 3447 m->mdmreg[REG_ECHO] |= BIT_ECHO; 3448 break; 3449 default: 3450 PARSE_ERROR; 3451 } 3452 break; 3453 case 'H': 3454 /* H - On/Off-hook */ 3455 p++; 3456 switch (*p) { 3457 case '0': 3458 p++; 3459 isdn_tty_on_hook(info); 3460 break; 3461 case '1': 3462 p++; 3463 isdn_tty_off_hook(); 3464 break; 3465 default: 3466 isdn_tty_on_hook(info); 3467 break; 3468 } 3469 break; 3470 case 'I': 3471 /* I - Information */ 3472 p++; 3473 isdn_tty_at_cout("\r\nLinux ISDN", info); 3474 switch (*p) { 3475 case '0': 3476 case '1': 3477 p++; 3478 break; 3479 case '2': 3480 p++; 3481 isdn_tty_report(info); 3482 break; 3483 case '3': 3484 p++; 3485 snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge); 3486 isdn_tty_at_cout(ds, info); 3487 break; 3488 default:; 3489 } 3490 break; 3491#ifdef DUMMY_HAYES_AT 3492 case 'L': 3493 case 'M': 3494 /* only for be compilant with common scripts */ 3495 /* no function */ 3496 p++; 3497 isdn_getnum(&p); 3498 break; 3499#endif 3500 case 'O': 3501 /* O - Go online */ 3502 p++; 3503 if (info->msr & UART_MSR_DCD) 3504 /* if B-Channel is up */ 3505 isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? RESULT_CONNECT : RESULT_CONNECT64000, info); 3506 else 3507 isdn_tty_modem_result(RESULT_NO_CARRIER, info); 3508 return; 3509 case 'Q': 3510 /* Q - Turn Emulator messages on/off */ 3511 p++; 3512 switch (isdn_getnum(&p)) { 3513 case 0: 3514 m->mdmreg[REG_RESP] |= BIT_RESP; 3515 break; 3516 case 1: 3517 m->mdmreg[REG_RESP] &= ~BIT_RESP; 3518 break; 3519 default: 3520 PARSE_ERROR; 3521 } 3522 break; 3523 case 'S': 3524 /* S - Set/Get Register */ 3525 p++; 3526 if (isdn_tty_cmd_ATS(&p, info)) 3527 return; 3528 break; 3529 case 'V': 3530 /* V - Numeric or ASCII Emulator-messages */ 3531 p++; 3532 switch (isdn_getnum(&p)) { 3533 case 0: 3534 m->mdmreg[REG_RESP] |= BIT_RESPNUM; 3535 break; 3536 case 1: 3537 m->mdmreg[REG_RESP] &= ~BIT_RESPNUM; 3538 break; 3539 default: 3540 PARSE_ERROR; 3541 } 3542 break; 3543 case 'Z': 3544 /* Z - Load Registers from Profile */ 3545 p++; 3546 if (info->msr & UART_MSR_DCD) { 3547 info->online = 0; 3548 isdn_tty_on_hook(info); 3549 } 3550 isdn_tty_modem_reset_regs(info, 1); 3551 break; 3552 case '+': 3553 p++; 3554 switch (*p) { 3555#ifdef CONFIG_ISDN_AUDIO 3556 case 'F': 3557 p++; 3558 if (isdn_tty_cmd_PLUSF(&p, info)) 3559 return; 3560 break; 3561 case 'V': 3562 if ((!(m->mdmreg[REG_SI1] & 1)) || 3563 (m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM)) 3564 PARSE_ERROR; 3565 p++; 3566 if (isdn_tty_cmd_PLUSV(&p, info)) 3567 return; 3568 break; 3569#endif /* CONFIG_ISDN_AUDIO */ 3570 case 'S': /* SUSPEND */ 3571 p++; 3572 isdn_tty_get_msnstr(ds, &p); 3573 isdn_tty_suspend(ds, info, m); 3574 break; 3575 case 'R': /* RESUME */ 3576 p++; 3577 isdn_tty_get_msnstr(ds, &p); 3578 isdn_tty_resume(ds, info, m); 3579 break; 3580 case 'M': /* MESSAGE */ 3581 p++; 3582 isdn_tty_send_msg(info, m, p); 3583 break; 3584 default: 3585 PARSE_ERROR; 3586 } 3587 break; 3588 case '&': 3589 p++; 3590 if (isdn_tty_cmd_ATand(&p, info)) 3591 return; 3592 break; 3593 default: 3594 PARSE_ERROR; 3595 } 3596 } 3597#ifdef CONFIG_ISDN_AUDIO 3598 if (!info->vonline) 3599#endif 3600 isdn_tty_modem_result(RESULT_OK, info); 3601} 3602 3603/* Need own toupper() because standard-toupper is not available 3604 * within modules. 3605 */ 3606#define my_toupper(c) (((c >= 'a') && (c <= 'z')) ? (c & 0xdf) : c) 3607 3608/* 3609 * Perform line-editing of AT-commands 3610 * 3611 * Parameters: 3612 * p inputbuffer 3613 * count length of buffer 3614 * channel index to line (minor-device) 3615 */ 3616static int 3617isdn_tty_edit_at(const char *p, int count, modem_info *info) 3618{ 3619 atemu *m = &info->emu; 3620 int total = 0; 3621 u_char c; 3622 char eb[2]; 3623 int cnt; 3624 3625 for (cnt = count; cnt > 0; p++, cnt--) { 3626 c = *p; 3627 total++; 3628 if (c == m->mdmreg[REG_CR] || c == m->mdmreg[REG_LF]) { 3629 /* Separator (CR or LF) */ 3630 m->mdmcmd[m->mdmcmdl] = 0; 3631 if (m->mdmreg[REG_ECHO] & BIT_ECHO) { 3632 eb[0] = c; 3633 eb[1] = 0; 3634 isdn_tty_at_cout(eb, info); 3635 } 3636 if ((m->mdmcmdl >= 2) && (!(strncmp(m->mdmcmd, "AT", 2)))) 3637 isdn_tty_parse_at(info); 3638 m->mdmcmdl = 0; 3639 continue; 3640 } 3641 if (c == m->mdmreg[REG_BS] && m->mdmreg[REG_BS] < 128) { 3642 /* Backspace-Function */ 3643 if ((m->mdmcmdl > 2) || (!m->mdmcmdl)) { 3644 if (m->mdmcmdl) 3645 m->mdmcmdl--; 3646 if (m->mdmreg[REG_ECHO] & BIT_ECHO) 3647 isdn_tty_at_cout("\b", info); 3648 } 3649 continue; 3650 } 3651 if (cmdchar(c)) { 3652 if (m->mdmreg[REG_ECHO] & BIT_ECHO) { 3653 eb[0] = c; 3654 eb[1] = 0; 3655 isdn_tty_at_cout(eb, info); 3656 } 3657 if (m->mdmcmdl < 255) { 3658 c = my_toupper(c); 3659 switch (m->mdmcmdl) { 3660 case 1: 3661 if (c == 'T') { 3662 m->mdmcmd[m->mdmcmdl] = c; 3663 m->mdmcmd[++m->mdmcmdl] = 0; 3664 break; 3665 } else 3666 m->mdmcmdl = 0; 3667 /* Fall through, check for 'A' */ 3668 case 0: 3669 if (c == 'A') { 3670 m->mdmcmd[m->mdmcmdl] = c; 3671 m->mdmcmd[++m->mdmcmdl] = 0; 3672 } 3673 break; 3674 default: 3675 m->mdmcmd[m->mdmcmdl] = c; 3676 m->mdmcmd[++m->mdmcmdl] = 0; 3677 } 3678 } 3679 } 3680 } 3681 return total; 3682} 3683 3684/* 3685 * Switch all modem-channels who are online and got a valid 3686 * escape-sequence 1.5 seconds ago, to command-mode. 3687 * This function is called every second via timer-interrupt from within 3688 * timer-dispatcher isdn_timer_function() 3689 */ 3690void 3691isdn_tty_modem_escape(void) 3692{ 3693 int ton = 0; 3694 int i; 3695 int midx; 3696 3697 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 3698 if (USG_MODEM(dev->usage[i]) && (midx = dev->m_idx[i]) >= 0) { 3699 modem_info *info = &dev->mdm.info[midx]; 3700 if (info->online) { 3701 ton = 1; 3702 if ((info->emu.pluscount == 3) && 3703 time_after(jiffies, 3704 info->emu.lastplus + PLUSWAIT2)) { 3705 info->emu.pluscount = 0; 3706 info->online = 0; 3707 isdn_tty_modem_result(RESULT_OK, info); 3708 } 3709 } 3710 } 3711 isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, ton); 3712} 3713 3714/* 3715 * Put a RING-message to all modem-channels who have the RI-bit set. 3716 * This function is called every second via timer-interrupt from within 3717 * timer-dispatcher isdn_timer_function() 3718 */ 3719void 3720isdn_tty_modem_ring(void) 3721{ 3722 int ton = 0; 3723 int i; 3724 3725 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 3726 modem_info *info = &dev->mdm.info[i]; 3727 if (info->msr & UART_MSR_RI) { 3728 ton = 1; 3729 isdn_tty_modem_result(RESULT_RING, info); 3730 } 3731 } 3732 isdn_timer_ctrl(ISDN_TIMER_MODEMRING, ton); 3733} 3734 3735/* 3736 * For all online tty's, try sending data to 3737 * the lower levels. 3738 */ 3739void 3740isdn_tty_modem_xmit(void) 3741{ 3742 int ton = 1; 3743 int i; 3744 3745 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 3746 modem_info *info = &dev->mdm.info[i]; 3747 if (info->online) { 3748 ton = 1; 3749 isdn_tty_senddown(info); 3750 isdn_tty_tint(info); 3751 } 3752 } 3753 isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, ton); 3754} 3755 3756/* 3757 * Check all channels if we have a 'no carrier' timeout. 3758 * Timeout value is set by Register S7. 3759 */ 3760void 3761isdn_tty_carrier_timeout(void) 3762{ 3763 int ton = 0; 3764 int i; 3765 3766 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 3767 modem_info *info = &dev->mdm.info[i]; 3768 if (!info->dialing) 3769 continue; 3770 if (info->emu.carrierwait++ > info->emu.mdmreg[REG_WAITC]) { 3771 info->dialing = 0; 3772 isdn_tty_modem_result(RESULT_NO_CARRIER, info); 3773 isdn_tty_modem_hup(info, 1); 3774 } else 3775 ton = 1; 3776 } 3777 isdn_timer_ctrl(ISDN_TIMER_CARRIER, ton); 3778} 3779