/*
* 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 <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <ncurses.h>
#include <time.h>
#include <unistd.h>
#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);
}
}
syntax highlighted by Code2HTML, v. 0.9.1