#include #include #include #include #include #include #include #include #include /* kiss tnc routines for various - HEP/RWM */ int getbyte(),port,instat(); #define FEND 0300 /* Frame End */ #define FESC 0333 /* Frame Escape */ #define TFEND 0334 /* Transposed frame end */ #define TFESC 0335 /* Transposed frame escape */ #define SSIDMD 0x60 #define SSIDMS 0x61 unsigned char pkt[300],echo=0; unsigned long time_out,now; unsigned char line[336],dump=0; unsigned char *in_buf; FILE *dumpr,*dumpa; union REGS inreg,outreg; struct tm *gmt; unsigned char satellite=4,com_str[]="COM1:9600,N,8,1",*satname[]={"PACSAT", "DOVE","WEBER","LUSAT"},newsat=0,rawdmp[40],ascdmp[40]; struct eqn { unsigned char channel,name[16],units[9],ok,value; float a0,a1,a2; } tlmval[80]; void asc_enab(),asc_disab(); main(argc,argv) int argc; char *argv[]; { int ch,frame_l,i; long timeit,addr; unsigned char *buf,*bufc; void tlm(),status(),check_call(); i=1; while (argv[i] != NULL) { *argv[i] = toupper(*argv[i]); switch(*argv[i]) { case 'C':{ strcpy(com_str,argv[i]); break; } default : break; } i++; } /* Set up serial port */ setcom(com_str); _clearscreen(_GCLEARSCREEN); main_men(); while(1) { if (kbhit() != 0) { ch = getch(); ch = toupper(ch); switch(ch) { case 'F':{ if(dump) { dump = 0; fcloseall(); } _settextwindow(1,1,25,80); _clearscreen(_GCLEARSCREEN); _outtext("Input raw data file to read: "); scanf("%s",rawdmp); if ((dumpr = fopen(rawdmp,"rb")) == NULL) { _outtext("\nFile Not found. Strike a key"); getch(); main_men(); break; } _clearscreen(_GCLEARSCREEN); _settextposition(1,70); if (satellite != 4) _outtext(satname[satellite]); else _outtext(" "); _settextposition(25,55); _outtext("Q=Quit,space to continue"); frame_l = 0; while (frame_l != -1) { frame_l=dsk_frame(pkt,dumpr); if (frame_l < 0 ) { fclose(dumpr); _settextposition(25,55); while(kbhit() != 0) getch(); _outtext("File end, strike a key "); getch(); break; } ax25r(pkt,frame_l); if (strstr(line,">TLM") != NULL) { check_call(); tlm(); } else if ((buf=strstr(line,"uptime")) != NULL) { _settextposition(1,1); _outtext(buf); } else if (strstr(line,">STATUS") != NULL) { check_call(); status(); frame_l = getch(); if (toupper(frame_l) == 'Q') break; } if(newsat) { _settextposition(1,70); _outtext(" "); _settextposition(1,70); _outtext(satname[satellite]); newsat = 0; } } _clearscreen(_GCLEARSCREEN); main_men(); break; } case 'D': { if (dump == 0) { _settextwindow(1,1,25,80); _clearscreen(_GCLEARSCREEN); _outtext("Input raw data dump file: "); scanf("%s",rawdmp); _outtext("\nInput ascii dump file: "); scanf("%s",ascdmp); if (((dumpr = fopen(rawdmp,"ab")) == NULL) || ((dumpa = fopen(ascdmp,"at")) == NULL)) { perror("Error opening files"); dump = 0; } else dump = 1; main_men(); } else { dump = 0; fcloseall(); } break; } case 'Q': { _clearscreen(_GCLEARSCREEN); asc_disab(port); fcloseall(); exit(0); } case 'U':{ _clearscreen(_GCLEARSCREEN); system("command"); main_men(); break; } case 'T': { _settextwindow(1,1,25,80); _clearscreen(_GCLEARSCREEN); _settextposition(1,70); if (satellite != 4) _outtext(satname[satellite]); else _outtext(" "); _settextposition(25,60); _outtext("Keystroke to Quit"); do { if (instat(port)){ frame_l=rec_frame(pkt); if (frame_l != -1) { ax25r(pkt,frame_l); if (dump) { fputs(line,dumpa); } if (strstr(line,">TLM") != NULL) { check_call(); tlm(); } else if (strstr(line,">STATUS") != NULL) { check_call(); status(); } else if ((in_buf=strstr(line,"uptime")) != NULL) { _settextposition(1,1); _outtext(in_buf); } }} if(newsat) { _settextposition(1,70); _outtext(" "); _settextposition(1,70); _outtext(satname[satellite]); newsat = 0; } } while (kbhit() == 0); if (getch() == 0) getch(); _clearscreen(_GCLEARSCREEN); main_men(); break; } } } _settextwindow(1,1,24,80); do { if(newsat) { _settextwindow(25,1,25,80); _settextposition(1,1); _outtext(" "); _settextposition(1,1); _outtext(satname[satellite]); _settextwindow(1,1,24,80); newsat = 0; } if (instat(port) != 0) { _settextposition(24,1); frame_l=rec_frame(pkt); if (frame_l != -1) { ax25r(pkt,frame_l); check_call(); _outtext(line); if (dump) fputs(line,dumpa); } } } while (kbhit() == 0); } } /* Decode the raw KISS frames which have been stored on DISK*/ int dsk_frame(ubuf,dat_file) unsigned char *ubuf; FILE *dat_file; { int c,frame_size; unsigned char *buf; while((c=fgetc(dat_file)) != FEND) if (c == EOF) if (feof(dat_file)) return -1; kludge_garb: buf=ubuf; while( (c = fgetc(dat_file)) == FEND) if (c == EOF) if (feof(dat_file)) return -1; c = fgetc(dat_file); /* ignore KISS type code */ if (c == EOF) if(feof(dat_file)) return -1; frame_size = 0; do{ if(c == FESC){ c = fgetc(dat_file); switch(c){ case TFEND: *buf++ = FEND; frame_size++; break; case TFESC: *buf++ = FESC; frame_size++; break; default: break; } } else{ if (c == EOF) if(feof(dat_file)) return -1; *buf++ = c; frame_size++; } c = fgetc(dat_file); } while( c != FEND); /* If we get a short frame becuase the main loop doesn't read except after it sends a command, go and restart this frame, i.e., assume that the "end" is the start of a new frame. */ if (frame_size<14) goto kludge_garb; return frame_size; } /* Telemetry format routine */ static unsigned char *t; void tlm() { int a,b; unsigned char *print_tlm(); if ((t=strchr(in_buf,':')) != NULL){ t=in_buf; } else return; while (sscanf(t," %x:%x",&a,&b)==2) { _settextposition(3+(a/3),(a%3)*26+1); printf("%-25.25s ",print_tlm(a,b)); t= t+6; } } /* Decode the telemetry from the tlm table values */ static unsigned char printit[40]; unsigned char *print_tlm(chan,value) unsigned char chan,value; { float fvalue; struct eqn *ptr; ptr = &tlmval[chan]; if (ptr->ok == 1) { ptr->value = value; fvalue = value; fvalue = fvalue * (fvalue * ptr->a2 + ptr->a1) + ptr->a0; sprintf(printit,"%-14.14s %7.3f %c ",ptr->name,fvalue,ptr->units[0]); } else *printit=0; return printit; } /* Menu routine */ main_men() { _settextwindow(25,1,25,80); _clearscreen(_GCLEARSCREEN); if (satellite != 4) { _settextposition(25,1); _outtext(satname[satellite]); } _settextposition(1,10); _outtext("D = Toggle Dump, T = Tlm Decode, F = Decode File, Q = Quit"); _settextwindow(1,1,24,80); } /* Decode the status line from the telemetry */ void status() { int tx,txp,bcr,sb; _settextposition(25,1); switch (satellite) { case 0: { sscanf(&in_buf[9]," %2X",&bcr); sscanf(&in_buf[18]," %2X",&txp); sscanf(&in_buf[21]," %2X",&tx); sscanf(&in_buf[27]," %2X",&sb); sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X SbT:%1X BCR:%2X", 1^(tx&1),1^((tx&2)>>1),txp&0xF,(sb>>7)^1,bcr); _outtext(line); break; } case 1 :{ sscanf(&in_buf[9]," %2X",&bcr); sscanf(&in_buf[18]," %2X",&txp); sscanf(&in_buf[21]," %2X",&tx); sscanf(&in_buf[27]," %2X",&sb); sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X SbT:%1X BCR:%2X", (tx&1),((tx&2)>>1),txp&0xF,(sb>>7)^1,bcr); _outtext(line); break; } case 2: { sscanf(&in_buf[9]," %2X",&bcr); sscanf(&in_buf[18]," %2X",&txp); sscanf(&in_buf[21]," %2X",&tx); sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X, BCR:%2X", 1^(tx&1),1^((tx&2)>>1),txp&0xF,bcr); _outtext(line); break; } case 3: { sscanf(&in_buf[9]," %2X",&bcr); sscanf(&in_buf[18]," %2X",&txp); sscanf(&in_buf[21]," %2X",&tx); sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X, BCR:%2X", 1^(tx&1),1^((tx&2)>>1),txp&0xF,bcr); _outtext(line); break; } } } /* Make sure we are decoding with the correct equations, if not, then read in the appropriate file */ void check_call() { FILE *tlm_dat; unsigned char tmpsat,tlmline[81]; struct eqn *ptr; for(tmpsat=0;tmpsat<4;tmpsat++) { if(strstr(line,satname[tmpsat]) != NULL) { if (tmpsat != satellite) { satellite = tmpsat; newsat = 1; if((tlm_dat=fopen(satname[tmpsat],"rt")) == NULL) { puts("OOPS, you forgot to leave those files around!"); fcloseall(); exit(0); } tmpsat = 0; memset(tlmval,0,80*sizeof(tlmval[0])); while (fgets(tlmline,80,tlm_dat) != NULL) { ptr = &tlmval[tmpsat++]; sscanf(tlmline," %X",&ptr->channel); strncpy(ptr->name,&tlmline[6],15); *(strchr(ptr->name,':')) = 0; ptr->name[15]=0; sscanf(&tlmline[21]," %f",&ptr->a0); sscanf(&tlmline[34]," %f",&ptr->a1); sscanf(&tlmline[46]," %f",&ptr->a2); sscanf(&tlmline[59],"%7s",ptr->units); ptr->units[8]=0; ptr->ok=1; } fclose(tlm_dat); } return; } } } /* Horrible AX.25 handler, receive only */ ax25r(frame,framel) unsigned char *frame; int framel; { unsigned char *buf,*bufc,lineptr=0; int i,j,k,endadr=0; buf = bufc = frame; buf[framel]=0; /* Find the end of the address field */ do { /* Fix up addresses and SSID's into readable form */ /* Pick off the ssid from the shit in byte 7 of each address */ k = bufc[6]&1; bufc[6] = ((bufc[6] >> 1) & 0x0F); if (bufc[6] < 10) bufc[6] += '0'; else bufc[6] += 'A'-10; /* Shift the bits where they belong in each character of the address */ for(i=0;i<6;i++) { bufc[i] >>= 1; } bufc += 7; endadr++; } while ( k == 0); /* Output header line */ /* For each callsign field */ /* Output a dash, SSID, and arrow pointing to direction, screw the heard/digipeated bit */ bufc = &buf[7]; for(j=0;j<6;j++) line[lineptr++] = bufc[j]; line[lineptr++] ='-'; line[lineptr++] = buf[13]; line[lineptr++] ='>'; for(j=0;j<6;j++) line[lineptr++] = buf[j]; line[lineptr++] ='-'; line[lineptr++] = buf[6]; line[lineptr++]=' '; /* line[lineptr++]='V'; line[lineptr++]=' ';*/ /* Output the call and SSID of repeaters */ /* for(i=endadr-1,bufc=buf+(endadr-1)*7;i>=2;i--,bufc -= 7) { for(j=0;j<6;j++) line[lineptr++] =bufc[j]; line[lineptr++] = '-'; line[lineptr++] = bufc[6]; line[lineptr++] = ' '; } line[lineptr++] = ' ';*/ /* Is it a U frame, I frame, or S frame ? */ buf = frame + 7*endadr; switch((*buf) & 0x1) { case 0 : { /* It is an I frame */ while ((bufc=strchr(&buf[2],'\r')) != NULL) *bufc = '\n'; sprintf(&line[lineptr],"NR=%1u P/F=%1u NS=%1u PID=%2X\n%s", (unsigned) (((*buf)&0xE0)>>5), (unsigned) (((*buf)&0x10)>>4), (unsigned)(((*buf)&0xF)>>1), (unsigned) buf[1],&buf[2]); bufc = &line[strlen(line)-1]; if (*bufc != '\n') { *(bufc+1) = '\n'; *(bufc+2) = 0; } break; } case 1: { switch( (*buf) & 0x2) { case 0: { switch ((*buf) & 0xC) { case 0: { sprintf(&line[lineptr],"RR NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5), (unsigned) ((*buf) & 0x10)>>4); break; } case 4: { sprintf(&line[lineptr],"RNR NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5), (unsigned) ((*buf) & 0x10)>>4); break; } case 8: { sprintf(&line[lineptr],"REJ NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5), (unsigned) ((*buf) & 0x10)>>4); break; } } break; } case 2:{ switch(((*buf) & 0xE0)>>5) { case 0 :{ if ((*buf & 0x0C) != 0) sprintf(&line[lineptr]," DM\n"); else { while ((bufc=strchr(&buf[2],'\r')) != NULL) *bufc = '\n'; in_buf = &buf[2]; time(&now); gmt = gmtime(&now); sprintf(&line[lineptr],"%s%s",asctime(gmt),in_buf); bufc = &line[strlen(line)-1]; if (*bufc != '\n') { *(bufc+1) = '\n'; *(bufc+2) = 0; } } break; } case 1: { sprintf(&line[lineptr]," SABM\n"); break; } case 2: { sprintf(&line[lineptr]," DISC\n"); break; } case 3: { sprintf(&line[lineptr]," UA\n"); break; } case 4: { sprintf(&line[lineptr]," FRMR"); break; } } break; } } break; } } } int rec_frame(ubuf) unsigned char *ubuf; { unsigned char c; int frame_size; unsigned char *buf; time(&time_out); time_out+=3; while(getbyte() != FEND) { time(&now); if (now>time_out) return -1; } kludge_garb: buf=ubuf; /* wait for start of frame */ while( (c = getbyte()) == FEND) { time(&now); if (now>time_out) return -1; } /* ignore any extra FENDS */ c = getbyte(); /* ignore KISS type code */ frame_size = 0; do{ time(&now); if (now>time_out) return -1; if(c == FESC){ c = getbyte(); switch(c){ case TFEND: *buf++ = FEND; frame_size++; break; case TFESC: *buf++ = FESC; frame_size++; break; default: break; } } else{ *buf++ = c; frame_size++; } c = getbyte(); } while( c != FEND); /* If we get a short frame because the main loop doesn't read except after it sends a command, go and restart this frame, i.e., assume that the "end" is the start of a new frame. */ if (frame_size<14) goto kludge_garb; return frame_size; } /* Following serial io routines are taken from Quiktrak */ static unsigned char b1[8] = { '1', '1', '3', '6', '1', '2', '4', '9' }; static unsigned char b2[8] = { '1', '5', '0', '0', '2', '4', '8', '6' }; static unsigned char pars[4] = { 'N', 'O', 'N', 'E' }; static unsigned char stops[2] = { '1', '2' }; static unsigned char wlens[4] = { '?', '?', '7', '8' }; /*setcom, sets up the COM port*/ setcom(setstr) unsigned char *setstr; { unsigned char *p; int baud, par, stop, wlen; short ok; union REGS inreg, outreg; /* * Command line to upper case. */ for (p = setstr; *p; p++) if (islower(*p)) *p = toupper(*p); /* * Find port number. */ for (p = setstr; *p && (*p != ':'); p++); if (*p != ':') { error("No colon after COMn"); return; } port = (int) (*(p - 1) - '0') - 1; if ((port < 0) || (port > 7)) { error("Port number out of range"); return; } p++; if (!*p) { error("Parameters missing"); return; } /* * Find baud rate. */ ok = 0; for (baud = 0; !ok && (baud < 8); baud++) { ok = (*p == b1[baud]) && (*(p + 1) == b2[baud]); } baud--; if (!ok) { error("Baud rate not correct"); return; } for (; *p && (*p != ','); p++); if (!*p++) { error("Missing parameter"); return; } if (!*p) { error("Missing parameter"); return; } /* * Find parity. */ ok = 0; for (par = 0; !ok && (par < 4); par++) { ok = (pars[par] == *p); } par--; if (!ok) { error("Parity not N, E, or O"); return; } for (; *p && (*p != ','); p++); if (!*p++) { error("Missing parameter"); return; } if (!*p) { error("Missing parameter"); return; } /* * Find word length. */ ok = 0; for (wlen = 0; !ok && (wlen < 4); wlen++) { ok = (wlens[wlen] == *p); } wlen--; if (!ok) { error("Word length is not 7 or 8"); return; } for (; *p && (*p != ','); p++); if (!*p++) { error("Missing parameter"); return; } if (!*p) { error("Missing parameter"); return; } /* * Find number of stop bits. */ ok = 0; for (stop = 0; !ok && (stop < 2); stop++) { ok = (stops[stop] == *p); } stop--; if (!ok) { error("Number of stop bits not 1 or 2"); return; } /* Compute control byte */ inreg.h.al = 32 * baud + 8 * par + 4 * stop + wlen; printf(" COM%d:%c%c,%c,%c,%c = %x\n", port + 1, b1[baud], b2[baud], pars[par], wlens[wlen], stops[stop], inreg.h.al); inreg.x.dx = port; inreg.h.ah = 0; int86 (0x14, &inreg, &outreg); /* Set the speed,etc using the BIOS */ asc_enab(port); /* Turn on interrupt handler */ } int getbyte() { int x; do{ time(&now); if (now>time_out) return -1; else{ x = rcvbyte(port); } } while(x == -1); x &= 0xff; if (dump) fputc(x,dumpr); return x; } error(str) char *str; { perror(str); exit(0); }