/* * Merlin query program v1.1.1 * Copyright 1999 Nicholas Sayer * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #define TARGET_IP "10.0.0.1" #define TARGET_PORT 4950 /* color pairs */ #define RED 1 #define YELLOW 2 #define GREEN 3 #define NORM 4 /* predefined as the "normal" color */ #define N_COLORS 5 char use_color=0; /* * Recvfrom for only 1 seconds, bailing out otherwise */ int recvtime(int fd,unsigned char *buf,int bufsiz) { fd_set set; struct timeval tv; int size; FD_ZERO(&set); FD_SET(fd,&set); tv.tv_sec=1; tv.tv_usec=0; if (select(fd+1,&set,NULL,&set,&tv)!=1) { return -1; } return recvfrom(fd,buf,bufsiz,0,NULL,0); } char *fancy_bytes(int n) { static char buf[BUFSIZ]; if (n>1024*1024) { sprintf(buf,"%3.2f M",((float)n)/(1024.0*1024.0)); return buf; } if (n>1024) { sprintf(buf,"%3.2f K",((float)n)/1024.0); return buf; } sprintf(buf,"%d",n); return buf; } int fetchparm(int fd, struct sockaddr_in *addr, int block, int parm, unsigned char *bf,int bfsiz) { int size; bf[0]=0x80; bf[1]=2; bf[2]=0; bf[3]=block; bf[4]=parm; sendto(fd,bf,5,0,(struct sockaddr *)addr,sizeof(*addr)); size=recvtime(fd,bf,bfsiz); if (size<0) { return -1; } if (size!=bf[1]+(bf[2]<<8)+3) { return -1; } if (bf[5]!=0) { return -1; } return size; } error(msg) char *msg; { erase(); move(LINES/2,(COLS-strlen(msg))/2); if (use_color) color_set(RED,NULL); printw(msg); if (use_color) color_set(NORM,NULL); } redgreen_yesno(char *msg,char n) { if (n) { if (use_color) color_set(GREEN,NULL); printw("%s%s\n",msg,"YES"); if (use_color) color_set(NORM,NULL); } else { if (use_color) color_set(RED,NULL); printw("%s%s\n",msg,"no"); if (use_color) color_set(NORM,NULL); } } main() { int fd,size,c; struct sockaddr_in addr; unsigned char buf[1024]; WINDOW *win; time_t t; win=initscr(); if (has_colors()) { start_color(); if (COLOR_PAIRS>=N_COLORS) use_color++; } if (use_color) { init_pair(RED,COLOR_RED,COLOR_BLACK); init_pair(YELLOW,COLOR_YELLOW,COLOR_BLACK); init_pair(GREEN,COLOR_GREEN,COLOR_BLACK); init_pair(NORM,COLOR_WHITE,COLOR_BLACK); } cbreak(); noecho(); nodelay(win,TRUE); leaveok(win,TRUE); while(1) { int tos; if ((fd=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP))<0) { perror("socket()"); exit(1); } tos = IPTOS_LOWDELAY; setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); if (inet_aton(TARGET_IP,&(addr.sin_addr))!=1) { perror("inet_aton()"); exit(1); } addr.sin_port=htons(TARGET_PORT); addr.sin_family=AF_INET; /* * Command 0 returns ID frame 1 */ buf[0]=0; sendto(fd,buf,1,0,(struct sockaddr *)&addr,sizeof(addr)); size=recvtime(fd,buf,sizeof(buf)); if (size<=0) { error("Timeout reading status frame 1"); goto skip; } if (use_color) color_set(NORM,NULL); move(0,0); printw("EID: %02x:%02x:%02x:%02x:%02x:%02x\n",buf[1],buf[2],buf[3], buf[4],buf[5],buf[6]); printw("Firmware rev: %s\n",buf+7); printw("Equipment model: %s\n\n",buf+7+strlen(buf+7)+1); /* * Command 2 returns status frame 3 */ buf[0]=2; sendto(fd,buf,1,0,(struct sockaddr *)&addr,sizeof(addr)); size=recvtime(fd,buf,sizeof(buf)); if (size<=0) { error("Timeout reading status frame 3"); goto skip; } redgreen_yesno("Channel acquired: ", buf[1]&1); redgreen_yesno("Link established: ", buf[1]&2); redgreen_yesno(" Registered: ", buf[1]&4); if (use_color) color_set((buf[3]==0)?GREEN:RED,NULL); printw(" Last reg. error: %d\n",buf[3]); if (use_color) color_set(NORM,NULL); if (use_color) color_set((buf[4]!=4)?RED:GREEN,NULL); printw(" RRM state: "); switch(buf[4]) { case 0:printw("Inactive\n\n"); break; case 1:printw("Wide Area Scan\n\n"); break; case 2:printw("Wide Area Search\n\n"); break; case 3:printw("Quality Check\n\n"); break; case 4:printw("Channel Acquired\n\n"); break; case 5:printw("Reference Scan\n\n"); break; case 6:printw("Channel Search\n\n"); break; case 7:printw("Direted Hop\n\n"); break; case 8:printw("Sleep\n\n"); break; case 9:printw("RSSI Channel Scan\n\n"); break; default:printw("Unknown\n\n"); break; } if (use_color) color_set(NORM,NULL); printw(" SPI: %d\n",buf[12]<<8|buf[13]); printw(" SPNI: %d\n",buf[16]<<8|buf[17]); printw(" WASI: %d\n",buf[14]<<8|buf[15]); printw("cell ID: %d\n",buf[18]<<8|buf[19]); printw("channel: %d\n",buf[6]<<8|buf[7]); printw(" color: %d\n\n",buf[5]); if (use_color) { if (buf[8]<16) color_set(RED,NULL); else if (buf[8]<21) color_set(YELLOW,NULL); else color_set(GREEN,NULL); } printw(" RSSI: %d db\n",-115+buf[8]); if (use_color) color_set(NORM,NULL); if (use_color) { if (buf[9]<4) color_set(GREEN,NULL); else color_set(RED,NULL); } printw(" BLER: %d\n",buf[9]); if (use_color) color_set(NORM,NULL); size=fetchparm(fd,&addr,0x40,0x21,buf,sizeof(buf)); if (size<=0) { error("Timeout fetching parameter 0x40/0x21"); goto skip; } if (use_color) { if (buf[7]<25) color_set(GREEN,NULL); else if (buf[7]<50) color_set(YELLOW,NULL); else color_set(RED,NULL); } printw("NDBC busy: %d %%\n\n",buf[7]); if (use_color) color_set(NORM,NULL); size=fetchparm(fd,&addr,0x40,0x20,buf,sizeof(buf)); if (size<=0) { error("Timeout fetching parameter 0x40/0x20"); goto skip; } printw("counts (packets / bytes) - RX: %5d / %-10s ",buf[7]|buf[8]<<8, fancy_bytes((((((buf[14]<<8) | buf[13])<<8) | buf[12])<<8) | buf[11]) ); printw("TX: %5d / %-10s\n",buf[9]|buf[10]<<8, fancy_bytes((((((buf[18]<<8) | buf[17])<<8) | buf[16])<<8) | buf[15]) ); skip: move(0,69); time(&t); strftime(buf,sizeof(buf),"%r",localtime(&t)); printw("%s",buf); close(fd); refresh(); c=getch(); if (c==EOF || c==ERR) { sleep(1); continue; } if (c=='q' || c=='Q') { endwin(); exit(0); } if (c=='\014') /* ^L */ clearok(win,TRUE); } }