/* * AX530IN utilitY * * 2008-02-04 Kouichi Hirabayashi */ #include #include #include #include #include #include #include #include #include #define SPEED B115200 #define TIMEOUT 5 void onalarm(); void onint(); #ifndef OLDSIGNAL struct sigaction saalrm, osaalrm; #endif int dflg; /* debug info. */ int fflg; /* CSID, fileld strength */ int data[20]; char *etab[] = { "圏外", "微弱", "弱 ", "中 ", "良 ", "良好", "最良" }; int fd; char port[64]; /* AX530IN デバイス */ char *telno; /* 自番号 */ char *mnf; /* 製造元 */ char *code; /* 製品コード */ char *ver; /* ファームウェアバージョン */ int lnk; /* 空き基地局数 */ char *cmd; /* プログラム名 */ char buf[BUFSIZ]; main(argc, argv) char **argv; { char *s; int i, k, n; cmd = argv[0]; while (--argc > 0 && (*++argv)[0] == '-') for (s = argv[0]+1; *s; s++) switch (*s) { case 'd': dflg++; break; case 'f': fflg++; break; case 'p': if (s[1]) ++s; else { if (argc == 1) Usage(); --argc; s = *++argv; } strcpy(port, s); s += strlen(s) - 1; break; default: Usage(1); } getPort(); #ifdef OLDSIGNAL signal(SIGALRM, onalarm); #else saalrm.sa_handler = onalarm; sigemptyset(&saalrm.sa_mask); saalrm.sa_flags = 0; sigaction(SIGALRM, &saalrm, &osaalrm); #endif fd = serOpen(port, SPEED); signal(SIGINT, onint); sleep(1); init(fd); printf("--- AX530IN 受信状況 ---\n"); for (;;) { n = k = check(fd); if (k >= 6) k = 6; printf("%s(%02d/%02d)", etab[k], lnk, n); for (i = 0; i < k; i++) printf("*"); for ( ; i < 6; i++) printf(" "); for (i = 1; i <= n; i++) printf(" %d", data[i]); printf("\n"); if (fflg) { field(fd); check(fd); /* このとき lnk が 0 になってしまう */ } } serClose(fd); return 0; } check(fd) { int i, r; char *p; getResp(fd, "at@@lnk\r", &p); lnk = 0; sscanf(p, "%d", &lnk); free(p); usleep(500000); serPuts(fd, "at@@lvl\r"); for (i = -1; ; ) { r = serGets(fd, buf, sizeof(buf)); if (*buf == '\n') continue; if (strncmp(buf, "OK", 2) == 0) break; if (i > -1) sscanf(buf, "%d", &data[i]); i++; } return data[0]; } field(fd) { int i, r; char *p; serPuts(fd, "AT@K20\r"); for (;;) { r = serGets(fd, buf, sizeof(buf)); if (*buf == '\n' || strncmp(buf, "AT", 2) == 0) continue; if (strncmp(buf, "OK", 2) == 0) break; *strchr(buf, '\n') = '\0'; printf("%s\n", buf); } return 0; } init(fd) { int i, r; char *p; getResp(fd, "ATZ", NULL); getResp(fd, "ATI6", &telno); getResp(fd, "ATI3", &mnf); getResp(fd, "ATI4", &code); getResp(fd, "ATI5", &ver); printf("%s %s %s\n", mnf, code, ver); printf("TEL %s", telno); getResp(fd, "AT#Q3", &p); if (strstr(p, "IN") != NULL) { printf(" 圏内\n"); break; } else { printf(" 圏外\n"); sleep(1); } return 0; } getResp(fd, req, res) char *req, **res; { int r; char *strsave(); sprintf(buf, "%s\r", req); serPuts(fd, buf); for (;;) { r = serGets(fd, buf, sizeof(buf)); if (*buf == '\n' || strncmp(buf, "AT", 2) == 0) continue; if (strncmp(buf, "OK", 2) == 0) break; *strchr(buf, '\n') = '\0'; if (res != NULL) *res = strsave(buf); } return 0; } char *strsave(s) char *s; { char *p; if ((p = (char *)malloc(strlen(s) + 1)) == NULL) error("Memory over.", (char *)0); return strcpy(p, s); } serOpen(port, speed) char *port; { struct termios tios; int fd; if ((fd = open(port, O_RDWR)) == -1) error("can't open %s", port); tios.c_iflag = ICRNL; tios.c_oflag = 0; tios.c_cflag = CLOCAL|CREAD|CS8|HUPCL|CRTSCTS; tios.c_lflag = ICANON; tios.c_cc[VEOL] = '\n'; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = 100; if (cfsetospeed(&tios, speed) == -1) error("cfsetospeed() failed.", (char *)0); if (cfsetispeed(&tios, speed) == -1) error("cfsetispeed() failed.", (char *)0); if (tcsetattr(fd, TCSANOW, &tios) == -1) error("ioctl(TCSANOW) failed", (char *)0); return fd; } serClose(fd) { return close(fd); } serPuts(fd, s) char *s; { int n; n = strlen(s); if (write(fd, s, strlen(s)) != n) return -1; return 0; } serGets(fd, s, n) char *s; { int r; alarm(TIMEOUT); if ((r = read(fd, s, n)) <= 0) error("Responce timeout", (char *)0); alarm(0); s[r] = '\0'; if (dflg && *buf != '\n') printf("%s", buf); return r; } void onalarm() { #ifdef OLDSIGNAL signal(SIGALRM, onalarm); #else saalrm.sa_handler = onalarm; sigemptyset(&saalrm.sa_mask); saalrm.sa_flags = 0; sigaction(SIGALRM, &saalrm, &osaalrm); #endif } getPort() { FILE *pfp; int n; if (*port != '\0') return 0; if ((pfp = popen("/sbin/dmesg", "r")) == NULL) error("Can't popen(%s, \"r\")", "/sbin/dmesg"); while (fgets(buf, sizeof(buf), pfp) != NULL) { if (strstr(buf, "") != NULL) { if (dflg) printf("%s", buf); sscanf(buf, "sio%d", &n); sprintf(port, "/dev/cuad%d", n); } } pclose(pfp); if (*port == '\0') error("Can't find NetIndex AX530IN Card.", (char *)0); return 0; } error(s, t) char *s, *t; { fprintf(stderr, s, t); fprintf(stderr, "\n"); exit(1); } void onint() { if (fd != 0) close(fd); exit(0); } Usage() { static char *t[] = { "コマンド %s - AX530IN 電波状況確認", "構文 %s [オプション]", "フラグ -p デバイス # AX530IN のデバイスファイル名を指定", "例 %s # AX530IN の受信状況確認", " %s -f # 3 局までの CSID(基地局ID)と電界強度も表示", " %s -p /dev/cuad4 # AX530IN のデバイスを指定", "解説 通信カード(AX530IN)の製造元、製品コード、ファームウェアバージョン、", "電話番号に続いて、通信ードが掴んでいるアンテナ局数と各局の電界強度、受信状況", "を下記の形式で表示します。電界強度は 5 段階表示で 5 が最高です。", "", " 電波状況(空き基地局数/アンテナ数)グラフ 電界強度 ..", "", "-f を指定すると 3 局までの CSID(基地局 Id) と電界強度(dBu)を表示します。", "AX530IN のデバイスファイル名は dmesg の出力から求めますので、通常は指定する", "必要はありません。", NULL }; int i; for (i = 0; t[i] != NULL; i++) { fprintf(stdout, t[i], cmd); fprintf(stdout, "\n"); } exit(1); }