diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 6b7eed722e43..b9f356b51b58 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -3,6 +3,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. @@ -1656,6 +1657,10 @@ isdn_tty_reset_profile(atemu *m) 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 @@ -2365,6 +2370,24 @@ isdn_tty_check_esc(const u_char *p, u_char plus, int count, int *pluscount, * For RING-message handle auto-ATA if register 0 != 0 */ +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) { @@ -2443,8 +2466,9 @@ isdn_tty_modem_result(int code, modem_info *info) 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); @@ -2471,9 +2495,9 @@ isdn_tty_modem_result(int code, modem_info *info) /* 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); @@ -2564,21 +2595,53 @@ isdn_tty_get_msnstr(char *n, char **p) * Get phone-number from modem-commandbuffer */ static void -isdn_tty_getdial(char *p, char *q, int cnt) -{ - int first = 1; - 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--; +isdn_tty_getdial(char *p, char *q, int max) +{ + int first = 0; + char *oq = q; + int sub = 0; + + 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': + break; } - if (!limit) - break; ++ max--; p++; first = 0; } @@ -3115,6 +3178,92 @@ isdn_tty_cmd_PLUSF(char **p, modem_info *info) #endif } +/* + * 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 */ @@ -3500,7 +3649,8 @@ isdn_tty_parse_at(modem_info *info) p++; if (info->msr & UART_MSR_DCD) /* if B-Channel is up */ - isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? RESULT_CONNECT : RESULT_CONNECT64000, info); + isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? + RESULT_CONNECT : RESULT_CONNECT64000, info); else isdn_tty_modem_result(RESULT_NO_CARRIER, info); return; @@ -3579,6 +3729,11 @@ isdn_tty_parse_at(modem_info *info) 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; } diff --git a/include/linux/isdn.h b/include/linux/isdn.h index df97c8444f5d..ee5395e18e22 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -305,6 +305,10 @@ typedef struct atemu { 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 ) */ @@ -449,6 +453,9 @@ typedef struct isdn_devt { 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 */