/* Davis Weather Tool - dwt 1.0.1 31-Jan-2008 * * Retrieves weather information from WeatherLink data logger * For use with Vantage Pro console or Weather Envoy * * Copyright (C) 2004 Con Tassios * This is FREE software licensed under the terms and conditions * of the GNU General Public License (GPL) version 2 * * usage: dwt COMMAND PARAMS [options] * * COMMANDS PARAMS * FRMT +FORMAT Output formatted observation fields as defined in format string * TAGS List observation tags used for format string * LIST List all observation fields * GETTIME Display time of receiver * SETTIME Set time of receiver to that of PC * TEST Test communications * WRD Display weather station type * VER Display firmware version * RXCHECK Display receiver statistics * * Options: * -s tty Specify alternate serial port * -r num Repeat FRMT command 'num' times * -d delay Delay after FRMT command, valid if -r option used * * * Examples: * dwt FRMT "+%.1{OUT_TEMP} %{OUT_HUMIDITY}\n" * 10.8 68 * * dwt FRMT "+%.1{OUT_TEMP/FAH} %{OUT_HUMIDITY}\n" * 51.4 68 * * * * Compiled & tested on: Red Hat Enterprise Linux 2.1AS * Compile using: gcc dwt.c -o dwt -lm * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEFAULT_SERIAL "/dev/ttyS1" #define BAUDRATE B19200 #define ACK "\006" #define LOOP_LEN 99 #define U_STR "KPH|MPH|MPS|FAH|CEL|HPA|IHG|MIL|INC|CLK" #define U_CMD "FRMT|TAGS|LIST|GETTIME|SETTIME|TEST|WRD|VER|RXCHECK" /* Wind speed */ #define U_KPH 1 /* Kilometers per hour */ #define U_MPH 2 /* Miles per hour */ #define U_MPS 3 /* Meters per second */ /* Temperature */ #define U_FAH 4 /* Fahrenheit */ #define U_CEL 5 /* Celcius */ /* Atmospheric pressure */ #define U_HPA 6 /* hPa */ #define U_IHG 7 /* Inches of HG */ /* Rainfall */ #define U_MIL 8 /* Millimeters */ #define U_INC 9 /* Inches */ #define U_CLK 10 /* Clicks */ /* Default output units to metric */ #define DEF_WS U_KPH #define DEF_TM U_CEL #define DEF_AP U_HPA #define DEF_RF U_MIL typedef struct dmap { char *tag; ushort ofs, len; void *(*fn)(char *, ushort, ushort, ushort); char type; char *desc; ushort conv; } map; void *_malloc(size_t size); ushort chk_crc(char *buf, ushort size); ushort get_double_byte(char *buf, ushort pos); ushort get_units(char *u); ushort get_cmd(char *u); ushort valid_cmd(char *cmd); ushort getack(int fd); ushort wake_recv(int fd); ushort read_bytes(int fd, char *buf, ushort len, ushort t); ushort expect(int fd, char *send, char *recv, ushort c); char *GET_loop(int fd); void translate_str(char *src, char *dst); void print_str(char *frmt, struct dmap *t, char *bp, char *u); void proc_frmt_str(char *str, char *bp); int open_serial_port(char *tty); void usage(char *s); void *GET_temp(char *buf, ushort ofs, ushort len, ushort conv); void *GET_barometer(char *buf, ushort ofs, ushort len, ushort conv); void *GET_humidity(char *buf, ushort ofs, ushort len, ushort conv); void *GET_rain(char *buf, ushort ofs, ushort len, ushort conv); void *GET_windspeed(char *buf, ushort ofs, ushort len, ushort conv); void *GET_winddirection(char *buf, ushort ofs, ushort len, ushort conv); void *GET_winddegree(char *buf, ushort ofs, ushort len, ushort conv); void *GET_dewpoint(char *buf, ushort ofs, ushort len, ushort conv); void *GET_windchill(char *buf, ushort ofs, ushort len, ushort conv); void *GET_heatindex(char *buf, ushort ofs, ushort len, ushort conv); void *GET_time(char *buf, ushort ofs, ushort len, ushort conv); void *GET_FIELD(char *fld, char *bp, ushort conv); void CMD_settime(int fd); void CMD_gettime(int fd); void CMD_test(int fd); void CMD_rxcheck(int fd); void CMD_ver(int fd); void CMD_wrd(int fd); void CMD_list(int fd); void CMD_frmt(int fd, char *frmt, ushort n, ushort d); void CMD_tags(); map t[] ={ { "IN_TEMP", 9, 2, GET_temp, 'F', "Indoor temperature", DEF_TM }, { "IN_HUMIDITY", 11, 1, GET_humidity, 'U', "Indoor humidity", 0 }, { "OUT_TEMP", 12, 2, GET_temp, 'F', "Outdoor temperature", DEF_TM }, { "OUT_HUMIDITY", 33, 1, GET_humidity, 'U', "Outdoor humidity", 0 }, { "DEW_POINT", 0, 0, GET_dewpoint, 'F', "Dewpoint", DEF_TM }, { "WIND_CHILL", 0, 0, GET_windchill, 'F', "Wind Chill", DEF_TM }, { "HEAT_INDEX", 0, 0, GET_heatindex, 'F', "Heat Index", DEF_TM }, { "BAROMETER", 7, 2, GET_barometer, 'F', "Barometer", DEF_AP }, { "WIND_DIRECTION", 16, 2, GET_winddirection, 'S', "Wind Direction", 0 }, { "WIND_DEGREE", 16, 2, GET_winddegree, 'U', "Wind Degree", 0 }, { "WIND_SPEED", 14, 1, GET_windspeed, 'U', "Wind Speed", DEF_WS }, { "RAIN_TODAY", 50, 2, GET_rain, 'F', "Rain today", DEF_RF }, { "RAIN_MONTH", 52, 2, GET_rain, 'F', "Rain month", DEF_RF }, { "RAIN_YEAR", 54, 2, GET_rain, 'F', "Rain year", DEF_RF }, { "SUNRISE", 91, 2, GET_time, 'U', "Sunrise", 0 }, { "SUNSET", 93, 2, GET_time, 'U', "Sunset", 0 }, }; ushort crc_table [] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, // 0x00 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, // 0x08 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, // 0x10 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, // 0x18 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, // 0x20 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, // 0x28 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, // 0x30 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, // 0x38 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, // 0x40 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, // 0x48 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, // 0x50 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, // 0x58 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, // 0x60 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, // 0x68 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, // 0x70 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, // 0x78 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, // 0x80 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, // 0x88 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, // 0x90 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, // 0x98 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, // 0xA0 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, // 0xA8 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, // 0xB0 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, // 0xB8 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, // 0xC0 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, // 0xC8 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, // 0xD0 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, // 0xD8 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, // 0xE0 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, // 0xE8 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, // 0xF0 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, // 0xF8 }; void *_malloc(size_t size) { void *p; p = malloc(size); if (!p) { fprintf(stderr,"dwt: malloc failed\n"); exit(-1); } return(p); } void *GET_temp(char *buf, ushort ofs, ushort len, ushort conv) { float *x; x = _malloc(sizeof(float)); *x = (float)get_double_byte(buf, ofs)/10; switch(conv) { case U_CEL : *x = (((*x - 32) *5) /9); break; case U_FAH : default: break; } return (x); } void *GET_barometer(char *buf, ushort ofs, ushort len, ushort conv) { float *x; x = _malloc(sizeof(float)); *x = (float)get_double_byte(buf, ofs); switch(conv) { case U_HPA : *x = *x * 0.03378; break; case U_IHG: default: *x = *x / 1000; break; } return(x); } void *GET_humidity(char *buf, ushort ofs, ushort len, ushort conv) { ushort *x; x = _malloc(sizeof(ushort)); *x = *(buf+ofs); return (x); } void *GET_rain(char *buf, ushort ofs, ushort len, ushort conv) { float *f; f = _malloc(sizeof(float)); *f = (float)get_double_byte(buf, ofs); switch(conv) { case U_MIL : *f = *f * 0.254; break; case U_INC : *f = *f * 0.01; break; case U_CLK : default: break; } return(f); } void *GET_windspeed(char *buf, ushort ofs, ushort len, ushort conv) { ushort *x; x = _malloc(sizeof(ushort)); *x = *(buf+ofs); switch(conv) { case U_KPH: *x = *x * 1.609344 + 0.5; break; case U_MPS: *x = *x * 1.609344 * 1000 / 3600; break; case U_MPH: default: break; } return (x); } void *GET_winddirection(char *buf, ushort ofs, ushort len, ushort conv) { char *w[] = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW" }; float r; ushort x; char *p; r = (float)get_double_byte(buf, ofs) + 11.25; if (r > 360) r = r - 360; x = r / 22.5; p = strdup(w[x]); return(p); } void *GET_winddegree(char *buf, ushort ofs, ushort len, ushort conv) { ushort *r; r = _malloc(sizeof(ushort)); *r = (ushort)get_double_byte(buf, ofs); return (r); } void *GET_FIELD(char *fld, char *bp, ushort conv) { int k; ENTRY e, *ep; struct dmap *tp; e.key = fld; ep = hsearch(e, FIND); if (ep) { k = (int)ep->data; tp = &t[k]; } return( ep ? tp->fn(bp, tp->ofs, tp->len, conv ? conv : tp->conv) : NULL ); } void *GET_dewpoint(char *buf, ushort ofs, ushort len, ushort conv) { float *temp, ews, num1, num2, *r; ushort *hum; temp = (float *)GET_FIELD("OUT_TEMP", buf, 0); hum = (ushort *)GET_FIELD("OUT_HUMIDITY", buf, 0); ews = *hum * 0.01 * exp((17.502 * *temp)/(240.9 + *temp)); num1 = 240.9 * (log(ews)); num2 = 17.5 - (log(ews)); *r = num1 / num2; free(temp); free(hum); switch(conv) { case U_CEL : break; case U_FAH : default: *r = ((*r * 9) / 5 )+ 32; break; } return(r); } void *GET_windchill(char *buf, ushort ofs, ushort len, ushort conv) { float *temp, *r; ushort *hum, *windspeed; r = _malloc(sizeof(float)); temp = (float *)GET_FIELD("OUT_TEMP", buf, U_FAH); hum = (ushort *)GET_FIELD("OUT_HUMIDITY", buf, 0); windspeed = (ushort *)GET_FIELD("WIND_SPEED", buf, U_MPH); if (*windspeed < 3) *r = *temp; else *r = 35.74 + (0.6215 * *temp) - (35.75 * expf(0.16*log(*windspeed))) + (0.4275 * *temp*(expf(0.16*log(*windspeed)))); switch(conv) { case U_CEL : *r = (((*r - 32) *5) /9); break; case U_FAH : default: break; } free(temp); free(hum); free(windspeed); return(r); } void *GET_heatindex(char *buf, ushort ofs, ushort len, ushort conv) { float *temp, *r, T; ushort *hum, H; r = _malloc(sizeof(float)); temp = (float *)GET_FIELD("OUT_TEMP", buf, U_FAH); hum = (ushort *)GET_FIELD("OUT_HUMIDITY", buf, 0); T = *temp; H = *hum; if (T < 80) *r = T; else *r = -42.379 + (2.04901523 * T) + (10.14333127 * H) - (0.22475541 * T * H) - (0.00683783 * pow(T,2)) - (0.05481717 * pow(H,2)) + (0.00122874 * pow(T,2) * H) + (0.00085282 * T * pow(H,2)) - (0.000001998 * pow(T*H,2)); switch(conv) { case U_CEL : *r = (((*r - 32) *5) /9); break; case U_FAH : default: break; } free(temp); free(hum); return(r); } void *GET_time(char *buf, ushort ofs, ushort len, ushort conv) { ushort *x; x = _malloc(sizeof(ushort)); *x = (ushort)get_double_byte(buf, ofs); return(x); } ushort chk_crc(char *buf, ushort size) { ushort i; ushort crc; crc=0; for (i = 0; i < size; i++) crc = crc_table [(crc >> 8) ^ (unsigned char )buf[i]] ^ (crc << 8); return(crc == 0); } ushort get_double_byte(char *buf, ushort pos) { return(((unsigned char)*(buf+pos+1) << 8) | (unsigned char)*(buf+pos)); } void translate_str(char *src, char *dst) { char *p1,*p2,*endbuf; strcpy(dst,src); endbuf = dst+strlen(dst); for (p1=src, p2=dst; *p1 && p2conv; l = strlen(frmt); switch(t->type) { case 'F': frmt[l]='f'; v1 = t->fn(bp, t->ofs, t->len,cu); printf(frmt, *v1); free(v1); break; case 'S': frmt[l]='s'; v2 = t->fn(bp, t->ofs, t->len,cu); printf(frmt, v2); free(v2); break; case 'U': frmt[l]='u'; v3 = t->fn(bp, t->ofs, t->len,cu); printf(frmt, *(ushort *)v3); free(v3); break; } fflush(stdout); } void proc_frmt_str(char *str, char *bp) { ushort i, j, n, mode, prn; int k; ENTRY e, *ep; char tbuf[30], *st, *et, *prbuf, *p, *u; struct dmap *tpa; i = j = mode = prn = 0; st = et = NULL; n = strlen(str); prbuf = calloc(1,n--); while (i <= n) { if (!mode && *(str+i) == '%') mode=1; if (*(str+i) == '{' && mode) { st = str+i; et = NULL; j = 1; while ( i+j <= n) { if (*(str+i+j) != '}') { j++; } else { et = str+i+j; mode=0; break; } } if (et != NULL && et - st > 1) { strncpy(tbuf, st+1, et-st-1); tbuf[et-st-1]='\0'; i+=j; } } if (i <= n && !et) { prbuf[prn++]=str[i]; } if (i == n && !et) { printf(prbuf); bzero(prbuf,n+1); prn=0; } if (et) { p = strtok(tbuf, "/"); u = strtok(NULL, "/"); e.key = p; ep = hsearch(e, FIND); if (ep) { k = (int)ep->data; tpa = &t[k]; print_str(prbuf, tpa, bp, u); } else { prbuf[prn]='s'; printf(prbuf,"-"); } et = NULL; bzero(prbuf,n+1); prn=0; } i++; } } ushort getack(int fd) { ushort i = 0,max = 4, x, ok = 0; unsigned char buf; do { x=read_bytes(fd, &buf, 1, 1); i++; if (x > 0 && buf == 6) { ok=1; } } while (!ok && (i < max)); return(ok); } int open_serial_port(char *tty) { int fd; struct termios t; fd = open(tty, O_RDWR | O_NOCTTY ); if (fd) { if (ioctl(fd, TIOCEXCL, NULL) < 0) { fprintf(stdout,"dwt: Cannot get exclusive lock on serial port\n"); exit(-1); } bzero(&t, sizeof(t)); t.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; t.c_iflag = IGNPAR ; t.c_oflag = 0; t.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); t.c_cc[VINTR] = 0; t.c_cc[VQUIT] = 0; t.c_cc[VERASE] = 0; t.c_cc[VKILL] = 0; t.c_cc[VEOF] = 4; t.c_cc[VTIME] = 5; t.c_cc[VMIN] = 0; t.c_cc[VSWTC] = 0; t.c_cc[VSTART] = 0; t.c_cc[VSTOP] = 0; t.c_cc[VSUSP] = 0; t.c_cc[VEOL] = 0; t.c_cc[VREPRINT] = 0; t.c_cc[VDISCARD] = 0; t.c_cc[VWERASE] = 0; t.c_cc[VLNEXT] = 0; t.c_cc[VEOL2] = 0; tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &t); } return(fd); } void usage(char *s) { if (s) printf("dwt: %s\n\n", s); else printf("Davis Weather Tool - dwt 1.0\n\n"); printf("usage: dwt COMMAND PARAMS [options] \n\ \n\ COMMANDS PARAMS \n\ FRMT +FORMAT Output formatted observation fields as defined in format string \n\ TAGS List observation tags used for format string \n\ LIST List all observation fields \n\ GETTIME Display time of receiver \n\ SETTIME Set time of receiver to that of PC \n\ TEST Test communications \n\ WRD Display weather station type \n\ VER Display firmware version \n\ RXCHECK Display receiver statistics \n\ \n\ Options:\n\ -s tty Specify alternate serial port\n\ -r num Repeat FRMT command 'num' times\n\ -d delay Delay after FRMT command, valid if -r option used\n\n"); exit(-1); } ushort wake_recv(int fd) { ushort x; x = expect(fd, "\n", "\n\r", 2); if (!x) { printf("wake_recv: unable to establish communications with receiver\n"); } return(x); } void CMD_settime(int fd) { ushort i, x, crc = 0, err = 0; time_t t; struct tm *tp; unsigned char buf[9]; x = expect(fd, "SETTIME\n", ACK, 1); if (x) { t = time(NULL); tp = localtime(&t); sprintf(buf,"%c%c%c%c%c%c",tp->tm_sec, tp->tm_min, tp->tm_hour, tp->tm_mday, tp->tm_mon+1, tp->tm_year); for (i = 0; i < 6; i++) crc = crc_table [(crc >> 8) ^ (unsigned char )buf[i]] ^ (crc << 8); sprintf(buf+6,"%c%c", crc >> 8, crc << 24 >> 24); x = expect(fd, buf, ACK, 1); if (x) { printf("settime: Time set to %02d:%02d:%02d %d-%d-%d\n", tp->tm_hour, tp->tm_min, tp->tm_sec, tp->tm_mday, tp->tm_mon+1, tp->tm_year+1900); sleep(1); } else err = 1; } else err = 1; if (err) printf("settime: failed to set time\n"); } void CMD_gettime(int fd) { ushort x, n, crc; unsigned char buf[9]; x = expect(fd,"GETTIME\r",ACK,10); if (!x) { printf("gettime: ACK not received\n"); } else { n = read_bytes(fd, buf, 8, 5); if (n) crc = chk_crc((unsigned char*)buf, 8); if (crc) printf("Receiver time currently - %02d:%02d:%02d %d-%d-%d\n", buf[2],buf[1],buf[0],buf[3],buf[4],buf[5]+1900); else printf("Communications error - CRC failed [%d]\n",crc); } } void CMD_test(int fd) { ushort n; unsigned char buf[8]; write(fd, "TEST\r", 5); n = read_bytes(fd, buf, sizeof(buf), 10); buf[n] = '\0'; if (n) printf("%s", buf); } void CMD_rxcheck(int fd) { ushort n; unsigned char buf[35]; write(fd, "RXCHECK\r", 8); n = read_bytes(fd, buf, sizeof(buf), 2); buf[n] = '\0'; if (n) printf("%s", buf); } void CMD_ver(int fd) { ushort n; unsigned char buf[18]; write(fd, "VER\r", 4); n = read_bytes(fd, buf, sizeof(buf), 3); buf[n] = '\0'; if (n) printf("%s", buf); } void CMD_wrd(int fd) { ushort n, x; unsigned char buf, cmd[7]; sprintf(cmd,"WRD%c%c\r",18,77); x = expect(fd, cmd, ACK, 1); if (x) { n=read_bytes(fd, &buf, 1, 10); printf("Davis Weather Station Type : "); switch(buf) { case 0: printf("Wizard III"); break; case 1: printf("Wizard II"); break; case 2: printf("Monitor"); break; case 3: printf("Perception"); break; case 4: printf("GroWeather"); break; case 5: printf("Energy Enviromonitor"); break; case 6: printf("Health Enviromonitor"); break; case 16: printf("Vantage Pro"); break; default: printf("Unknown"); break; } printf("\n\n"); } else { printf("wrd: failed\n"); } } char *GET_loop(int fd) { ushort x, i, r, res; char *buf; buf=_malloc(sizeof(char)*(LOOP_LEN+1)); r = 0; for (i = 0; i < 3; i++) { x = expect(fd, "\n", "\n\r", 2); if (!x) continue; x = expect(fd,"LOOP 1\n", ACK, 2); if (!x) continue; res = read_bytes(fd,buf,LOOP_LEN,10); if (res != LOOP_LEN) continue; if (chk_crc((unsigned char *)buf, LOOP_LEN)) { r=1; break; } } if (!r) { free(buf); buf = NULL; } return(buf); } void CMD_list(int fd) { ushort n; int i; char prbuf[10], *buf; ENTRY e, *ep; buf = GET_loop(fd); if (buf) { n = sizeof(t) / sizeof(map); hcreate(n); for (i = 0; i < n; i++) { e.key = t[i].tag; e.data = (char *)i; ep = hsearch(e, ENTER); } for (i=0; i len) bytes = len - x; x+=read(fd, p, bytes); p += bytes; } } while (!timeout && (p - buf < len)); return(x); } ushort expect(int fd, char *send, char *recv, ushort c) { ushort x, n, i, r; char *buf; i = strlen(recv); buf = _malloc(sizeof(char)*i); n = 0; do { write(fd, send, strlen(send)); x=read_bytes(fd, buf, i, 2); n++; } while (!x && n1 || delay>0) && (cmd != 1)) usage("Invalid options - only valid for FRMT command"); if (tty == NULL) tty = DEFAULT_SERIAL; if ((fd = open_serial_port(tty)) == -1) { fprintf(stderr,"dwt: Cannot open serial port"); exit(-1); } if (cmd != 2) wake_recv(fd); switch(cmd) { case 1 : CMD_frmt(fd, frmt, num, delay); break; case 2 : CMD_tags(); break; case 3 : CMD_list(fd); break; case 4 : CMD_gettime(fd); break; case 5 : CMD_settime(fd); break; case 6 : CMD_test(fd); break; case 7 : CMD_wrd(fd); break; case 8 : CMD_ver(fd); break; case 9 : CMD_rxcheck(fd); break; default : break; } close(fd); exit(0); }