18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* text2qos.c - Converts textual representation of QOS parameters to binary
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		encoding */
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */
58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if HAVE_CONFIG_H
78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <config.h>
88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdarg.h>
128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <ctype.h>
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <limits.h>
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "atm.h"
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define fetch __atmlib_fetch
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RATE_ERROR -2
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint __t2q_get_rate(const char **text,int up)
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    const char mult[] = "kKmMgGg";
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    const char *multiplier;
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *end;
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned int rate,fract;
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int power;
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!strncmp(*text,"max",3)) {
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*text += 3;
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return ATM_MAX_PCR;
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rate = strtoul(*text,&end,10);
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    power = fract = 0;
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*end == '.')
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (end++; *end && isdigit(*end); end++) {
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fract = fract*10+*end-48;
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (--power == -9) break;
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    multiplier = NULL;
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*end && (multiplier = strchr(mult,*end))) {
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	while (multiplier >= mult) {
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (rate > UINT_MAX/1000) return RATE_ERROR;
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rate *= 1000;
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    power += 3;
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    multiplier -= 2;
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	end++;
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (power && fract)
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (power < 0) {
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fract /= 10;
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    power++;
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else {
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fract *= 10;
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    power--;
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rate += fract;
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strlen(end) < 3) {
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (multiplier) return RATE_ERROR;
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else if (!strncmp(end,"cps",3)) end += 3;
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else if (!strncmp(end,"bps",3)) {
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		rate = (rate+(up ? 8*ATM_CELL_PAYLOAD-1 : 0))/8/
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		  ATM_CELL_PAYLOAD;
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		end += 3;
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    else if (multiplier) return RATE_ERROR;
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rate > INT_MAX) return RATE_ERROR;
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *text = end;
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return rate;
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int params(const char **text,struct atm_trafprm *a,
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project  struct atm_trafprm *b)
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int value;
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *end;
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*(*text)++ != ':') return -1;
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (1) {
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!**text) return -1;
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (fetch(text,"max_pcr=","pcr=","min_pcr=","max_sdu=","sdu=",
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	  NULL)) {
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 0:
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1;
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (a) a->max_pcr = value;
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (b) b->max_pcr = value;
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 1:
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1;
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (a) a->pcr = value;
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (b) b->pcr = value;
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 2:
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((value = __t2q_get_rate(text,1)) == RATE_ERROR) return -1;
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (value == ATM_MAX_PCR) return -1;
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (a) a->min_pcr = value;
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (b) b->min_pcr = value;
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 3:
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 4:
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		value = strtol(*text,&end,10);
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (value < 0) return -1;
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		*text = end;
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (a) a->max_sdu = value;
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (b) b->max_sdu = value;
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    default:
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return 0;
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!**text) break;
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (*(*text)++ != ',') return -1;
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint text2qos(const char *text,struct atm_qos *qos,int flags)
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int traffic_class,aal;
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    traffic_class = ATM_NONE;
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    aal = ATM_NO_AAL;
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    do {
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	static const unsigned char aal_number[] = { ATM_AAL0, ATM_AAL5 };
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	int item;
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	item = fetch(&text,"!none","ubr","cbr","vbr","abr","aal0","aal5",NULL);
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	switch (item) {
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 1:
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 2:
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* we don't support VBR yet */
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 4:
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		traffic_class = item;
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 5:
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case 6:
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		aal = aal_number[item-5];
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    default:
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return -1;
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (*text == ',' ? text++ : 0);
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!traffic_class) return -1;
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (qos && !(flags & T2Q_DEFAULTS)) memset(qos,0,sizeof(*qos));
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (qos) qos->txtp.traffic_class = qos->rxtp.traffic_class = traffic_class;
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (qos && aal) qos->aal = aal;
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!*text) return 0;
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (params(&text,qos ? &qos->txtp : NULL,qos ? &qos->rxtp : NULL))
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!*text) return 0;
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (fetch(&text,"tx","rx",NULL)) {
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case 0:
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!fetch(&text,":none",NULL)) {
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (qos) qos->txtp.traffic_class = ATM_NONE;
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (*text == ',') text++;
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (params(&text,qos ? &qos->txtp : NULL,NULL)) return -1;
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case 1:
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    text -= 2;
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return -1;
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!*text) return 0;
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fetch(&text,"rx",NULL)) return -1;
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!fetch(&text,":none",NULL) && qos) qos->rxtp.traffic_class = ATM_NONE;
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else if (params(&text,qos ? &qos->rxtp : NULL,NULL)) return -1;
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return *text ? -1 : 0;
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
181