1 /******************************************************************************
2  *
3  *	(C)Copyright 1998,1999 SysKonnect,
4  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5  *
6  *	See the file "skfddi.c" for further information.
7  *
8  *	This program is free software; you can redistribute it and/or modify
9  *	it under the terms of the GNU General Public License as published by
10  *	the Free Software Foundation; either version 2 of the License, or
11  *	(at your option) any later version.
12  *
13  *	The information in this file is provided "AS IS" without warranty.
14  *
15  ******************************************************************************/
16 
17 
18 /*
19 	parser for SMT parameters
20 */
21 
22 #include "h/types.h"
23 #include "h/fddi.h"
24 #include "h/smc.h"
25 #include "h/smt_p.h"
26 
27 #define KERNEL
28 #include "h/smtstate.h"
29 
30 #ifndef	lint
31 static const char ID_sccs[] = "@(#)smtparse.c	1.12 98/10/06 (C) SK " ;
32 #endif
33 
34 #ifdef	sun
35 #define _far
36 #endif
37 
38 /*
39  * convert to BCLK units
40  */
41 #define MS2BCLK(x)      ((x)*12500L)
42 #define US2BCLK(x)      ((x/10)*125L)
43 
44 /*
45  * parameter table
46  */
47 static struct s_ptab {
48 	char	*pt_name ;
49 	u_short	pt_num ;
50 	u_short	pt_type ;
51 	u_long	pt_min ;
52 	u_long	pt_max ;
53 } ptab[] = {
54 	{ "PMFPASSWD",0,	0 } ,
55 	{ "USERDATA",1,		0 } ,
56 	{ "LERCUTOFFA",2,	1,	4,	15	} ,
57 	{ "LERCUTOFFB",3,	1,	4,	15	} ,
58 	{ "LERALARMA",4,	1,	4,	15	} ,
59 	{ "LERALARMB",5,	1,	4,	15	} ,
60 	{ "TMAX",6,		1,	5,	165	} ,
61 	{ "TMIN",7,		1,	5,	165	} ,
62 	{ "TREQ",8,		1,	5,	165	} ,
63 	{ "TVX",9,		1,	2500,	10000	} ,
64 #ifdef ESS
65 	{ "SBAPAYLOAD",10,	1,	0,	1562	} ,
66 	{ "SBAOVERHEAD",11,	1,	50,	5000	} ,
67 	{ "MAXTNEG",12,		1,	5,	165	} ,
68 	{ "MINSEGMENTSIZE",13,	1,	0,	4478	} ,
69 	{ "SBACATEGORY",14,	1,	0,	0xffff	} ,
70 	{ "SYNCHTXMODE",15,	0 } ,
71 #endif
72 #ifdef SBA
73 	{ "SBACOMMAND",16,	0 } ,
74 	{ "SBAAVAILABLE",17,	1,	0,	100	} ,
75 #endif
76 	{ 0 }
77 } ;
78 
79 /* Define maximum string size for values and keybuffer */
80 #define MAX_VAL	40
81 
82 /*
83  * local function declarations
84  */
85 static u_long parse_num() ;
86 static int parse_word() ;
87 
88 #ifdef SIM
89 #define DB_MAIN(a,b,c)	printf(a,b,c)
90 #else
91 #define DB_MAIN(a,b,c)
92 #endif
93 
94 /*
95  * BEGIN_MANUAL_ENTRY()
96  *
97  *	int smt_parse_arg(struct s_smc *,char _far *keyword,int type,
98 		char _far *value)
99  *
100  *	parse SMT parameter
101  *	*keyword
102  *		pointer to keyword, must be \0, \n or \r terminated
103  *	*value	pointer to value, either char * or u_long *
104  *		if char *
105  *			pointer to value, must be \0, \n or \r terminated
106  *		if u_long *
107  *			contains binary value
108  *
109  *	type	0: integer
110  *		1: string
111  *	return
112  *		0	parameter parsed ok
113  *		!= 0	error
114  *	NOTE:
115  *		function can be called with DS != SS
116  *
117  *
118  * END_MANUAL_ENTRY()
119  */
smt_parse_arg(smc,keyword,type,value)120 int smt_parse_arg(smc,keyword,type,value)
121 struct s_smc *smc ;
122 char _far *keyword ;
123 int type ;
124 char _far *value ;
125 {
126 	char		keybuf[MAX_VAL+1];
127 	char		valbuf[MAX_VAL+1];
128 	char		c ;
129 	char 		*p ;
130 	char		*v ;
131 	char		*d ;
132 	u_long		val = 0 ;
133 	struct s_ptab	*pt ;
134 	int		st ;
135 	int		i ;
136 
137 	/*
138 	 * parse keyword
139 	 */
140 	if ((st = parse_word(keybuf,keyword)))
141 		return(st) ;
142 	/*
143 	 * parse value if given as string
144 	 */
145 	if (type == 1) {
146 		if ((st = parse_word(valbuf,value)))
147 			return(st) ;
148 	}
149 	/*
150 	 * search in table
151 	 */
152 	st = 0 ;
153 	for (pt = ptab ; (v = pt->pt_name) ; pt++) {
154 		for (p = keybuf ; (c = *p) ; p++,v++) {
155 			if (c != *v)
156 				break ;
157 		}
158 		if (!c && !*v)
159 			break ;
160 	}
161 	if (!v)
162 		return(-1) ;
163 #if	0
164 	printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ;
165 #endif
166 	/*
167 	 * set value in MIB
168 	 */
169 	if (pt->pt_type)
170 		val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ;
171 	switch (pt->pt_num) {
172 	case 0 :
173 		v = valbuf ;
174 		d = (char *) smc->mib.fddiPRPMFPasswd ;
175 		for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++)
176 			*d++ = *v++ ;
177 		DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ;
178 		break ;
179 	case 1 :
180 		v = valbuf ;
181 		d = (char *) smc->mib.fddiSMTUserData ;
182 		for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++)
183 			*d++ = *v++ ;
184 		DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ;
185 		break ;
186 	case 2 :
187 		smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ;
188 		DB_MAIN("SET %s = %d\n",
189 			pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ;
190 		break ;
191 	case 3 :
192 		smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ;
193 		DB_MAIN("SET %s = %d\n",
194 			pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ;
195 		break ;
196 	case 4 :
197 		smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ;
198 		DB_MAIN("SET %s = %d\n",
199 			pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ;
200 		break ;
201 	case 5 :
202 		smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ;
203 		DB_MAIN("SET %s = %d\n",
204 			pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ;
205 		break ;
206 	case 6 :			/* TMAX */
207 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
208 		smc->mib.a[PATH0].fddiPATHT_MaxLowerBound =
209 			(u_long) -MS2BCLK((long)val) ;
210 		break ;
211 	case 7 :			/* TMIN */
212 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
213 		smc->mib.m[MAC0].fddiMACT_Min =
214 			(u_long) -MS2BCLK((long)val) ;
215 		break ;
216 	case 8 :			/* TREQ */
217 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
218 		smc->mib.a[PATH0].fddiPATHMaxT_Req =
219 			(u_long) -MS2BCLK((long)val) ;
220 		break ;
221 	case 9 :			/* TVX */
222 		DB_MAIN("SET %s = %d \n",pt->pt_name,val) ;
223 		smc->mib.a[PATH0].fddiPATHTVXLowerBound =
224 			(u_long) -US2BCLK((long)val) ;
225 		break ;
226 #ifdef	ESS
227 	case 10 :			/* SBAPAYLOAD */
228 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
229 		if (smc->mib.fddiESSPayload != val) {
230 			smc->ess.raf_act_timer_poll = TRUE ;
231 			smc->mib.fddiESSPayload = val ;
232 		}
233 		break ;
234 	case 11 :			/* SBAOVERHEAD */
235 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
236 		smc->mib.fddiESSOverhead = val ;
237 		break ;
238 	case 12 :			/* MAXTNEG */
239 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
240 		smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ;
241 		break ;
242 	case 13 :			/* MINSEGMENTSIZE */
243 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
244 		smc->mib.fddiESSMinSegmentSize = val ;
245 		break ;
246 	case 14 :			/* SBACATEGORY */
247 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
248 		smc->mib.fddiESSCategory =
249 			(smc->mib.fddiESSCategory & 0xffff) |
250 			((u_long)(val << 16)) ;
251 		break ;
252 	case 15 :			/* SYNCHTXMODE */
253 		/* do not use memcmp(valbuf,"ALL",3) because DS != SS */
254 		if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') {
255 			smc->mib.fddiESSSynchTxMode = TRUE ;
256 			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
257 		}
258 		/* if (!memcmp(valbuf,"SPLIT",5)) { */
259 		if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' &&
260 			valbuf[3] == 'I' && valbuf[4] == 'T') {
261 			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
262 			smc->mib.fddiESSSynchTxMode = FALSE ;
263 		}
264 		break ;
265 #endif
266 #ifdef	SBA
267 	case 16 :			/* SBACOMMAND */
268 		/* if (!memcmp(valbuf,"START",5)) { */
269 		if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' &&
270 			valbuf[3] == 'R' && valbuf[4] == 'T') {
271 			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
272 			smc->mib.fddiSBACommand = SB_START ;
273 		}
274 		/* if (!memcmp(valbuf,"STOP",4)) { */
275 		if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' &&
276 			valbuf[3] == 'P') {
277 			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
278 			smc->mib.fddiSBACommand = SB_STOP ;
279 		}
280 		break ;
281 	case 17 :			/* SBAAVAILABLE */
282 		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
283 		smc->mib.fddiSBAAvailable = (u_char) val ;
284 		break ;
285 #endif
286 	}
287 	return(0) ;
288 }
289 
parse_word(buf,text)290 static int parse_word(buf,text)
291 char *buf ;
292 char _far *text ;
293 {
294 	char		c ;
295 	char 		*p ;
296 	int		p_len ;
297 	int		quote ;
298 	int		i ;
299 	int		ok ;
300 
301 	/*
302 	 * skip leading white space
303 	 */
304 	p = buf ;
305 	for (i = 0 ; i < MAX_VAL ; i++)
306 		*p++ = 0 ;
307 	p = buf ;
308 	p_len = 0 ;
309 	ok = 0 ;
310 	while ( (c = *text++) && (c != '\n') && (c != '\r')) {
311 		if ((c != ' ') && (c != '\t')) {
312 			ok = 1 ;
313 			break ;
314 		}
315 	}
316 	if (!ok)
317 		return(-1) ;
318 	if (c == '"') {
319 		quote = 1 ;
320 	}
321 	else {
322 		quote = 0 ;
323 		text-- ;
324 	}
325 	/*
326 	 * parse valbuf
327 	 */
328 	ok = 0 ;
329 	while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n')
330 		&& (c != '\r')) {
331 		switch (quote) {
332 		case 0 :
333 			if ((c == ' ') || (c == '\t') || (c == '=')) {
334 				ok = 1 ;
335 				break ;
336 			}
337 			*p++ = c ;
338 			p_len++ ;
339 			break ;
340 		case 2 :
341 			*p++ = c ;
342 			p_len++ ;
343 			quote = 1 ;
344 			break ;
345 		case 1 :
346 			switch (c) {
347 			case '"' :
348 				ok = 1 ;
349 				break ;
350 			case '\\' :
351 				quote = 2 ;
352 				break ;
353 			default :
354 				*p++ = c ;
355 				p_len++ ;
356 			}
357 		}
358 	}
359 	*p++ = 0 ;
360 	for (p = buf ; (c = *p) ; p++) {
361 		if (c >= 'a' && c <= 'z')
362 			*p = c + 'A' - 'a' ;
363 	}
364 	return(0) ;
365 }
366 
parse_num(type,value,v,mn,mx,scale)367 static u_long parse_num(type,value,v,mn,mx,scale)
368 int type ;
369 char _far *value ;
370 char *v ;
371 u_long mn ;
372 u_long mx ;
373 int scale ;
374 {
375 	u_long	x = 0 ;
376 	char	c ;
377 
378 	if (type == 0) {		/* integer */
379 		u_long _far	*l ;
380 		u_long		u1 ;
381 
382 		l = (u_long _far *) value ;
383 		u1 = *l ;
384 		/*
385 		 * if the value is negative take the lower limit
386 		 */
387 		if ((long)u1 < 0) {
388 			if (- ((long)u1) > (long) mx) {
389 				u1 = 0 ;
390 			}
391 			else {
392 				u1 = (u_long) - ((long)u1) ;
393 			}
394 		}
395 		x = u1 ;
396 	}
397 	else {				/* string */
398 		int	sign = 0 ;
399 
400 		if (*v == '-') {
401 			sign = 1 ;
402 		}
403 		while ((c = *v++) && (c >= '0') && (c <= '9')) {
404 			x = x * 10 + c - '0' ;
405 		}
406 		if (scale == 10) {
407 			x *= 10 ;
408 			if (c == '.') {
409 				if ((c = *v++) && (c >= '0') && (c <= '9')) {
410 					x += c - '0' ;
411 				}
412 			}
413 		}
414 		if (sign)
415 			x = (u_long) - ((long)x) ;
416 	}
417 	/*
418 	 * if the value is negative
419 	 *	and the absolute value is outside the limits
420 	 *		take the lower limit
421 	 *	else
422 	 *		take the absoute value
423 	 */
424 	if ((long)x < 0) {
425 		if (- ((long)x) > (long) mx) {
426 			x = 0 ;
427 		}
428 		else {
429 			x = (u_long) - ((long)x) ;
430 		}
431 	}
432 	if (x < mn)
433 		return(mn) ;
434 	else if (x > mx)
435 		return(mx) ;
436 	return(x) ;
437 }
438 
439 #if 0
440 struct	s_smc	SMC ;
441 main()
442 {
443 	char	*p ;
444 	char	*v ;
445 	char	buf[100] ;
446 	int	toggle = 0 ;
447 
448 	while (gets(buf)) {
449 		p = buf ;
450 		while (*p && ((*p == ' ') || (*p == '\t')))
451 			p++ ;
452 
453 		while (*p && ((*p != ' ') && (*p != '\t')))
454 			p++ ;
455 
456 		v = p ;
457 		while (*v && ((*v == ' ') || (*v == '\t')))
458 			v++ ;
459 		if ((*v >= '0') && (*v <= '9')) {
460 			toggle = !toggle ;
461 			if (toggle) {
462 				u_long	l ;
463 				l = atol(v) ;
464 				smt_parse_arg(&SMC,buf,0,(char _far *)&l) ;
465 			}
466 			else
467 				smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
468 		}
469 		else {
470 			smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
471 		}
472 	}
473 	exit(0) ;
474 }
475 #endif
476