/****************************************************************************** * * (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 { 0 } } ; /* Define maximum string size for values and keybuffer */ #define MAX_VAL 40 /* * local function declarations */ static u_long parse_num() ; static int parse_word() ; #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(smc,keyword,type,value) 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(buf,text) 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(type,value,v,mn,mx,scale) 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