| /****************************************************************************** |
| * |
| * (C)Copyright 1998,1999 SysKonnect, |
| * a business unit of Schneider & Koch & Co. Datensysteme GmbH. |
| * |
| * See the file "skfddi.c" for further information. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * The information in this file is provided "AS IS" without warranty. |
| * |
| ******************************************************************************/ |
| |
| |
| /* |
| parser for SMT parameters |
| */ |
| |
| #include "h/types.h" |
| #include "h/fddi.h" |
| #include "h/smc.h" |
| #include "h/smt_p.h" |
| |
| #define KERNEL |
| #include "h/smtstate.h" |
| |
| #ifndef lint |
| static const char ID_sccs[] = "@(#)smtparse.c 1.12 98/10/06 (C) SK " ; |
| #endif |
| |
| #ifdef sun |
| #define _far |
| #endif |
| |
| /* |
| * convert to BCLK units |
| */ |
| #define MS2BCLK(x) ((x)*12500L) |
| #define US2BCLK(x) ((x/10)*125L) |
| |
| /* |
| * parameter table |
| */ |
| static struct s_ptab { |
| char *pt_name ; |
| u_short pt_num ; |
| u_short pt_type ; |
| u_long pt_min ; |
| u_long pt_max ; |
| } ptab[] = { |
| { "PMFPASSWD",0, 0 } , |
| { "USERDATA",1, 0 } , |
| { "LERCUTOFFA",2, 1, 4, 15 } , |
| { "LERCUTOFFB",3, 1, 4, 15 } , |
| { "LERALARMA",4, 1, 4, 15 } , |
| { "LERALARMB",5, 1, 4, 15 } , |
| { "TMAX",6, 1, 5, 165 } , |
| { "TMIN",7, 1, 5, 165 } , |
| { "TREQ",8, 1, 5, 165 } , |
| { "TVX",9, 1, 2500, 10000 } , |
| #ifdef ESS |
| { "SBAPAYLOAD",10, 1, 0, 1562 } , |
| { "SBAOVERHEAD",11, 1, 50, 5000 } , |
| { "MAXTNEG",12, 1, 5, 165 } , |
| { "MINSEGMENTSIZE",13, 1, 0, 4478 } , |
| { "SBACATEGORY",14, 1, 0, 0xffff } , |
| { "SYNCHTXMODE",15, 0 } , |
| #endif |
| #ifdef SBA |
| { "SBACOMMAND",16, 0 } , |
| { "SBAAVAILABLE",17, 1, 0, 100 } , |
| #endif |
| { NULL } |
| } ; |
| |
| /* Define maximum string size for values and keybuffer */ |
| #define MAX_VAL 40 |
| |
| /* |
| * local function declarations |
| */ |
| static u_long parse_num(int type, char _far *value, char *v, u_long mn, |
| u_long mx, int scale); |
| static int parse_word(char *buf, char _far *text); |
| |
| #ifdef SIM |
| #define DB_MAIN(a,b,c) printf(a,b,c) |
| #else |
| #define DB_MAIN(a,b,c) |
| #endif |
| |
| /* |
| * BEGIN_MANUAL_ENTRY() |
| * |
| * int smt_parse_arg(struct s_smc *,char _far *keyword,int type, |
| char _far *value) |
| * |
| * parse SMT parameter |
| * *keyword |
| * pointer to keyword, must be \0, \n or \r terminated |
| * *value pointer to value, either char * or u_long * |
| * if char * |
| * pointer to value, must be \0, \n or \r terminated |
| * if u_long * |
| * contains binary value |
| * |
| * type 0: integer |
| * 1: string |
| * return |
| * 0 parameter parsed ok |
| * != 0 error |
| * NOTE: |
| * function can be called with DS != SS |
| * |
| * |
| * END_MANUAL_ENTRY() |
| */ |
| int smt_parse_arg(struct s_smc *smc, char _far *keyword, int type, |
| char _far *value) |
| { |
| char keybuf[MAX_VAL+1]; |
| char valbuf[MAX_VAL+1]; |
| char c ; |
| char *p ; |
| char *v ; |
| char *d ; |
| u_long val = 0 ; |
| struct s_ptab *pt ; |
| int st ; |
| int i ; |
| |
| /* |
| * parse keyword |
| */ |
| if ((st = parse_word(keybuf,keyword))) |
| return(st) ; |
| /* |
| * parse value if given as string |
| */ |
| if (type == 1) { |
| if ((st = parse_word(valbuf,value))) |
| return(st) ; |
| } |
| /* |
| * search in table |
| */ |
| st = 0 ; |
| for (pt = ptab ; (v = pt->pt_name) ; pt++) { |
| for (p = keybuf ; (c = *p) ; p++,v++) { |
| if (c != *v) |
| break ; |
| } |
| if (!c && !*v) |
| break ; |
| } |
| if (!v) |
| return(-1) ; |
| #if 0 |
| printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ; |
| #endif |
| /* |
| * set value in MIB |
| */ |
| if (pt->pt_type) |
| val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ; |
| switch (pt->pt_num) { |
| case 0 : |
| v = valbuf ; |
| d = (char *) smc->mib.fddiPRPMFPasswd ; |
| for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++) |
| *d++ = *v++ ; |
| DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ; |
| break ; |
| case 1 : |
| v = valbuf ; |
| d = (char *) smc->mib.fddiSMTUserData ; |
| for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++) |
| *d++ = *v++ ; |
| DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ; |
| break ; |
| case 2 : |
| smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ; |
| DB_MAIN("SET %s = %d\n", |
| pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ; |
| break ; |
| case 3 : |
| smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ; |
| DB_MAIN("SET %s = %d\n", |
| pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ; |
| break ; |
| case 4 : |
| smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ; |
| DB_MAIN("SET %s = %d\n", |
| pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ; |
| break ; |
| case 5 : |
| smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ; |
| DB_MAIN("SET %s = %d\n", |
| pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ; |
| break ; |
| case 6 : /* TMAX */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.a[PATH0].fddiPATHT_MaxLowerBound = |
| (u_long) -MS2BCLK((long)val) ; |
| break ; |
| case 7 : /* TMIN */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.m[MAC0].fddiMACT_Min = |
| (u_long) -MS2BCLK((long)val) ; |
| break ; |
| case 8 : /* TREQ */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.a[PATH0].fddiPATHMaxT_Req = |
| (u_long) -MS2BCLK((long)val) ; |
| break ; |
| case 9 : /* TVX */ |
| DB_MAIN("SET %s = %d \n",pt->pt_name,val) ; |
| smc->mib.a[PATH0].fddiPATHTVXLowerBound = |
| (u_long) -US2BCLK((long)val) ; |
| break ; |
| #ifdef ESS |
| case 10 : /* SBAPAYLOAD */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| if (smc->mib.fddiESSPayload != val) { |
| smc->ess.raf_act_timer_poll = TRUE ; |
| smc->mib.fddiESSPayload = val ; |
| } |
| break ; |
| case 11 : /* SBAOVERHEAD */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.fddiESSOverhead = val ; |
| break ; |
| case 12 : /* MAXTNEG */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ; |
| break ; |
| case 13 : /* MINSEGMENTSIZE */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.fddiESSMinSegmentSize = val ; |
| break ; |
| case 14 : /* SBACATEGORY */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.fddiESSCategory = |
| (smc->mib.fddiESSCategory & 0xffff) | |
| ((u_long)(val << 16)) ; |
| break ; |
| case 15 : /* SYNCHTXMODE */ |
| /* do not use memcmp(valbuf,"ALL",3) because DS != SS */ |
| if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') { |
| smc->mib.fddiESSSynchTxMode = TRUE ; |
| DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ; |
| } |
| /* if (!memcmp(valbuf,"SPLIT",5)) { */ |
| if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' && |
| valbuf[3] == 'I' && valbuf[4] == 'T') { |
| DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ; |
| smc->mib.fddiESSSynchTxMode = FALSE ; |
| } |
| break ; |
| #endif |
| #ifdef SBA |
| case 16 : /* SBACOMMAND */ |
| /* if (!memcmp(valbuf,"START",5)) { */ |
| if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' && |
| valbuf[3] == 'R' && valbuf[4] == 'T') { |
| DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ; |
| smc->mib.fddiSBACommand = SB_START ; |
| } |
| /* if (!memcmp(valbuf,"STOP",4)) { */ |
| if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' && |
| valbuf[3] == 'P') { |
| DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ; |
| smc->mib.fddiSBACommand = SB_STOP ; |
| } |
| break ; |
| case 17 : /* SBAAVAILABLE */ |
| DB_MAIN("SET %s = %d\n",pt->pt_name,val) ; |
| smc->mib.fddiSBAAvailable = (u_char) val ; |
| break ; |
| #endif |
| } |
| return(0) ; |
| } |
| |
| static int parse_word(char *buf, char _far *text) |
| { |
| char c ; |
| char *p ; |
| int p_len ; |
| int quote ; |
| int i ; |
| int ok ; |
| |
| /* |
| * skip leading white space |
| */ |
| p = buf ; |
| for (i = 0 ; i < MAX_VAL ; i++) |
| *p++ = 0 ; |
| p = buf ; |
| p_len = 0 ; |
| ok = 0 ; |
| while ( (c = *text++) && (c != '\n') && (c != '\r')) { |
| if ((c != ' ') && (c != '\t')) { |
| ok = 1 ; |
| break ; |
| } |
| } |
| if (!ok) |
| return(-1) ; |
| if (c == '"') { |
| quote = 1 ; |
| } |
| else { |
| quote = 0 ; |
| text-- ; |
| } |
| /* |
| * parse valbuf |
| */ |
| ok = 0 ; |
| while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n') |
| && (c != '\r')) { |
| switch (quote) { |
| case 0 : |
| if ((c == ' ') || (c == '\t') || (c == '=')) { |
| ok = 1 ; |
| break ; |
| } |
| *p++ = c ; |
| p_len++ ; |
| break ; |
| case 2 : |
| *p++ = c ; |
| p_len++ ; |
| quote = 1 ; |
| break ; |
| case 1 : |
| switch (c) { |
| case '"' : |
| ok = 1 ; |
| break ; |
| case '\\' : |
| quote = 2 ; |
| break ; |
| default : |
| *p++ = c ; |
| p_len++ ; |
| } |
| } |
| } |
| *p++ = 0 ; |
| for (p = buf ; (c = *p) ; p++) { |
| if (c >= 'a' && c <= 'z') |
| *p = c + 'A' - 'a' ; |
| } |
| return(0) ; |
| } |
| |
| static u_long parse_num(int type, char _far *value, char *v, u_long mn, |
| u_long mx, int scale) |
| { |
| u_long x = 0 ; |
| char c ; |
| |
| if (type == 0) { /* integer */ |
| u_long _far *l ; |
| u_long u1 ; |
| |
| l = (u_long _far *) value ; |
| u1 = *l ; |
| /* |
| * if the value is negative take the lower limit |
| */ |
| if ((long)u1 < 0) { |
| if (- ((long)u1) > (long) mx) { |
| u1 = 0 ; |
| } |
| else { |
| u1 = (u_long) - ((long)u1) ; |
| } |
| } |
| x = u1 ; |
| } |
| else { /* string */ |
| int sign = 0 ; |
| |
| if (*v == '-') { |
| sign = 1 ; |
| } |
| while ((c = *v++) && (c >= '0') && (c <= '9')) { |
| x = x * 10 + c - '0' ; |
| } |
| if (scale == 10) { |
| x *= 10 ; |
| if (c == '.') { |
| if ((c = *v++) && (c >= '0') && (c <= '9')) { |
| x += c - '0' ; |
| } |
| } |
| } |
| if (sign) |
| x = (u_long) - ((long)x) ; |
| } |
| /* |
| * if the value is negative |
| * and the absolute value is outside the limits |
| * take the lower limit |
| * else |
| * take the absoute value |
| */ |
| if ((long)x < 0) { |
| if (- ((long)x) > (long) mx) { |
| x = 0 ; |
| } |
| else { |
| x = (u_long) - ((long)x) ; |
| } |
| } |
| if (x < mn) |
| return(mn) ; |
| else if (x > mx) |
| return(mx) ; |
| return(x) ; |
| } |
| |
| #if 0 |
| struct s_smc SMC ; |
| main() |
| { |
| char *p ; |
| char *v ; |
| char buf[100] ; |
| int toggle = 0 ; |
| |
| while (gets(buf)) { |
| p = buf ; |
| while (*p && ((*p == ' ') || (*p == '\t'))) |
| p++ ; |
| |
| while (*p && ((*p != ' ') && (*p != '\t'))) |
| p++ ; |
| |
| v = p ; |
| while (*v && ((*v == ' ') || (*v == '\t'))) |
| v++ ; |
| if ((*v >= '0') && (*v <= '9')) { |
| toggle = !toggle ; |
| if (toggle) { |
| u_long l ; |
| l = atol(v) ; |
| smt_parse_arg(&SMC,buf,0,(char _far *)&l) ; |
| } |
| else |
| smt_parse_arg(&SMC,buf,1,(char _far *)p) ; |
| } |
| else { |
| smt_parse_arg(&SMC,buf,1,(char _far *)p) ; |
| } |
| } |
| exit(0) ; |
| } |
| #endif |
| |