--- linux-2.6.36-/drivers/isdn/i4l/isdn_tty.c 2010-10-20 22:30:22.000000000 +0200 +++ linux-2.6.36/drivers/isdn/i4l/isdn_tty.c 2010-10-24 19:42:39.000000000 +0200 @@ -4,6 +4,7 @@ * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg + * 08/2002 Addition of +I commands by Birger Harzenetter (wimpy@yeti.dk) * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. @@ -1773,6 +1774,10 @@ m->profile[23] = 0; m->pmsn[0] = '\0'; m->plmsn[0] = '\0'; + strcpy(m->iprefix,"00"); + strcpy(m->nprefix,"0" ); + strcpy(m->prnum ,"0" ); + strcpy(m->nanum ,"0" ); } #ifdef CONFIG_ISDN_AUDIO @@ -2475,6 +2480,24 @@ */ static void +isdn_tty_modem_result_prCGPN(char *num, unsigned char typ, unsigned char pi, modem_info * info) +{ + atemu *m = &info->emu; + + typ=(typ>>4)&7; + pi=(pi>>5)&3; + isdn_tty_at_cout("\r\nCALLER NUMBER: ", info); + if (pi==1) isdn_tty_at_cout(m->prnum, info); + else if (pi==2) isdn_tty_at_cout(m->nanum, info); + else + { + if (typ==1 && m->iprefix[0]) isdn_tty_at_cout(m->iprefix, info); + if (typ==2 && m->nprefix[0]) isdn_tty_at_cout(m->nprefix, info); + isdn_tty_at_cout(num, info); + } +} + +static void isdn_tty_modem_result(int code, modem_info * info) { atemu *m = &info->emu; @@ -2553,8 +2576,8 @@ return; /* print CID, _before_ _every_ ring */ if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) { - isdn_tty_at_cout("\r\nCALLER NUMBER: ", info); - isdn_tty_at_cout(dev->num[info->drv_index], info); + isdn_tty_modem_result_prCGPN(dev->num[info->drv_index], + dev->numtyp[info->drv_index], dev->screen[info->drv_index], info); if (m->mdmreg[REG_CDN] & BIT_CDN) { isdn_tty_at_cout("\r\nCALLED NUMBER: ", info); isdn_tty_at_cout(info->emu.cpn, info); @@ -2581,9 +2604,8 @@ /* Print CID only once, _after_ 1st RING */ if ((m->mdmreg[REG_CIDONCE] & BIT_CIDONCE) && (m->mdmreg[REG_RINGCNT] == 1)) { - isdn_tty_at_cout("\r\n", info); - isdn_tty_at_cout("CALLER NUMBER: ", info); - isdn_tty_at_cout(dev->num[info->drv_index], info); + isdn_tty_modem_result_prCGPN(dev->num[info->drv_index], + dev->numtyp[info->drv_index], dev->screen[info->drv_index], info); if (m->mdmreg[REG_CDN] & BIT_CDN) { isdn_tty_at_cout("\r\nCALLED NUMBER: ", info); isdn_tty_at_cout(info->emu.cpn, info); @@ -2636,6 +2658,12 @@ if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) { return; } +#ifdef CONFIG_ISDN_AUDIO + if ( !info->vonline ) + tty_ldisc_flush(info->tty); +#else + tty_ldisc_flush(info->tty); +#endif if ((info->flags & ISDN_ASYNC_CHECK_CD) && (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) && (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) { @@ -2679,21 +2707,52 @@ static void isdn_tty_getdial(char *p, char *q,int cnt) { - int first = 1; + int first = 0; + char *oq = q; int limit = ISDN_MSNLEN - 1; /* MUST match the size of interface var to avoid buffer overflow */ - while (strchr(" 0123456789,#.*WPTSR-", *p) && *p && --cnt>0) { - if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) || - ((*p == 'R') && first) || - (*p == '*') || (*p == '#')) { - *q++ = *p; - limit--; + max--; + while (*p && (max > 0)) { + switch (*p) { + case '0':// normal digits + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '*': + case '#': + first=0; + *q++ = *p; + break; + case '+':// as first char only + case 'S': + case 'D': + case 'R': + if (first) *q++ = *p; + else *oq=0; + break; + case '.':// subadress - only once! + sub++; + *q++ = *p; + if (sub>1) *oq=0; + break; + case ' ':// ignore dialling method prefixes and + case '-':// 'optical' formatting + case 'W': + case ',': + case '(': + case ')': + case 'T': + case 'P': } - if(!limit) - break; + max--; p++; - first = 0; } *q = 0; } @@ -3229,6 +3288,92 @@ } /* + * Parse AT+I.. commands + */ +static int +isdn_tty_cmd_PLUSI(char **p, modem_info * info) +{ + atemu *m = &info->emu; + static char *icmd[] = + {"NNP", "NIP", "NNA", "NPR", NULL}; + int i, pp=0; + char param[8], reqtyp=0; + + i = 0; + while (icmd[i]) { + if (!strncmp(icmd[i], p[0], strlen(icmd[i]))) { + p[0] += strlen(icmd[i]); + break; + } + i++; + } + switch (*p[0]) { + case '?': + reqtyp=1; + p[0]++; + break; + case '=': + reqtyp=2; + p[0]++; + if (*p[0]=='?') { + reqtyp=3; + p[0]++; + } else { + while(*p[0] && *p[0]!=';' && pp<8) { + param[pp]=*p[0]; + pp++; + p[0]++; + } + if (pp>7) PARSE_ERROR1; + param[pp]=0; + } + break; + default: + PARSE_ERROR1; + } + switch (100*reqtyp+i) { + case 100: + isdn_tty_at_cout("\r\n", info); + isdn_tty_at_cout(m->nprefix, info); + break; + case 101: + isdn_tty_at_cout("\r\n", info); + isdn_tty_at_cout(m->iprefix, info); + break; + case 102: + isdn_tty_at_cout("\r\n", info); + isdn_tty_at_cout(m->nanum, info); + break; + case 103: + isdn_tty_at_cout("\r\n", info); + isdn_tty_at_cout(m->prnum, info); + break; + case 200: + strncpy(m->nprefix,param,8); + break; + case 201: + strncpy(m->iprefix,param,8); + break; + case 202: + strncpy(m->nanum,param,8); + break; + case 203: + strncpy(m->prnum,param,8); + break; + case 300: + case 301: + case 302: + case 303: + isdn_tty_at_cout("\r\n", info); + break; + default: + PARSE_ERROR1; + } + if (*p[0]==';') p[0]++; + return 0; +} + +/* * Parse AT+V.. commands */ static int @@ -3693,6 +3838,11 @@ p++; isdn_tty_send_msg(info, m, p); break; + case 'I': /* ISDN configuration */ + p++; + if (isdn_tty_cmd_PLUSI(&p, info)) + return; + break; default: PARSE_ERROR; } --- linux-2.6.36-/include/linux/isdn.h 2010-10-20 22:30:22.000000000 +0200 +++ linux-2.6.36/include/linux/isdn.h 2010-10-24 19:45:18.000000000 +0200 @@ -443,6 +443,10 @@ int carrierwait; /* Seconds of carrier waiting */ char mdmcmd[255]; /* Modem-Commandbuffer */ unsigned int charge; /* Charge units of current connection */ + char iprefix[8]; /* international prefix */ + char nprefix[8]; /* national prefix */ + char prnum[8]; /* presentation restricted */ + char nanum[8]; /* unknown number */ } atemu; /* Private data (similar to async_struct in ) */ @@ -596,6 +600,9 @@ int drvmap[ISDN_MAX_CHANNELS]; /* Map minor->driver-index */ int usage[ISDN_MAX_CHANNELS]; /* Used by tty/ip/voice */ char num[ISDN_MAX_CHANNELS][ISDN_MSNLEN]; + unsigned char numtyp[ISDN_MAX_CHANNELS]; /* type of number (and plan) + to make above unabigous */ + unsigned char screen[ISDN_MAX_CHANNELS]; /* Just to get the PI(ATM) */ /* Remote number of active ch.*/ int m_idx[ISDN_MAX_CHANNELS]; /* Index for mdm.... */ isdn_driver_t *drv[ISDN_MAX_DRIVERS]; /* Array of drivers */