home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Projekt: SCCD (Simple City-Call Decoder)
- ** Modul: pocsac.c
- ** Abhaengige module: none
- ** Copyright: gone
- ** Version: kappa 1.3E-15 (standallone COM1)
- ** Lastmodification: 15.11.92 19:38
- ** History:
- **
- **
- ** f1 = 465.970 MHz 512 Bits/sec
- ** f2 = 466.075 MHz 1200 Bits/sec
- ** f3 = 466.230 MHz 1200 Bits/sec
- **
- */
-
-
- /* compact memory model */
- /* keine flotingpoint emu */
- /* nested comments */
-
- /*
- **
- ** Includes fuer dieses Modul
- **
- */
- #include <stdio.h>
- #include <io.h>
- #include <dos.h>
- #include <fcntl.h>
- #include <alloc.h>
- #include <stdlib.h>
- #include <string.h>
- #include <conio.h>
- #include <time.h>
-
-
- /*
- **
- ** Defines die die arbeitsweise beeinflussen
- **
- */
- #define BITWRONG /* fallback wenn paritaet nicht stimmt */
- #define LOGFILE /* Wir schreiben eine Logfile fuer
- spaetere Datenbankauswertungen */
-
-
- /*
- **
- ** Defines fuer dieses Modul
- **
- */
- #define TIMER0CLOCK 1193182L /* Grundfreqenz des Timerbausteins */
- /* divisor für timer 0 : sample
- time=30/CLOCK_FREQ = 25.1 uSec */
- #define TIMER0B512 2330 /* Teilerrate fuer 512 Baud */
- #define TIMER0B1200 994 /* Teilerrate fuer 1200 Baud */
-
- #define MAXARRAY 60000 /* groesse des bitpuffers */
-
- #define SYNCRON 0x7cd215d8L /* Frame fuer das Syncronwort */
- #define SYNCINFO 0x7cd21436L /* Frame fuer das InforufSyncronwort */
- #define IDLE 0x7a89c197L /* Frame fuer das Idlewort */
-
- #define COMPORT 0x3f8 /* alles fuer COM1 */
- #define TXBYTE 0
- #define RXBYTE 0
- #define DIFLLB 0
- #define DIFLHB 1
- #define IER 1
- #define IIR 2
- #define LCR 3
- #define MCR 4
- #define LSR 5
- #define MSR 6
-
-
- #define GETSYNCR 1 /* Auf erstes Syncronwort warten */
- #define GETFRAME 2 /* Frames einladen */
-
-
- /*
- **
- ** Variablen / Speicher der von diesem Modul benutzt wird
- **
- */
- char *roh_daten_feld; /* zeiger auf pufferfeld */
- volatile unsigned int roh_daten_anfang; /* momentaner Anfang des
- Ringpuffers */
- volatile unsigned int roh_daten_ende; /* momentanes Ende des
- Ringpuffers */
- volatile unsigned int roh_daten_laenge; /* momentane Ringpufferlaenge
- (anzahl der Daten) */
-
- unsigned int tics; /* soviel Teilerschritte treten pro Bit
- auf */
- unsigned int tics_2; /* die Haelfte der Schritte */
-
- void interrupt (*old_vec)(); /* Adresse der alten Timerseviceroutine */
- void interrupt (*time_int)(); /* Adresse der alten Timer0 Routine */
- void interrupt time_i(); /* prototyp der Timer0 Routine */
- void interrupt lauf_er(); /* prototyp der bitholroutine */
- volatile int abbruch = 0; /* wir sollen das Programm verlassen */
- volatile int eine_sek_weg = 0; /* es ist eine Sekunde vergangen */
-
- #ifdef LOGFILE
- FILE *logfile = NULL; /* logfile fuer die daten */
- volatile int last_sync; /* Sekunden zaehlen wann das letzte
- mal ein Sync emfangen wurde */
- #endif
-
- char asc_time[40] = "Keine Zeit angegeben";
-
- static char numerik[] = { /* Decodierrung von Numerikpagern */
- '0',
- '8',
- '4',
- ' ',
- '2',
- '=',
- '6',
- ']',
- '1',
- '9',
- '5',
- '_',
- '3',
- 'U',
- '7',
- '['
- };
-
-
- /*
- **
- ** Routinen dieses Moduls
- **
- */
-
-
- char *
- strip_cr(char *cptr) /* CR+LF rausscheissen */
- {
- char *oldcptr;
-
- oldcptr = cptr;
- while (*cptr != '\0') {
- if (*cptr == '\r' || *cptr == '\n') *cptr = '\0';
- cptr++;
- }
- return(oldcptr);
- }
-
-
- #define ADRESS 0 /* Wir haben eine Adresse */
- #define DATEN 1 /* Wir haben Daten */
-
- void
- decode_frame(int framepos, unsigned long frame) /* Ein emfangenes Frame
- entschluesseln */
- {
- static unsigned long lastadress = 0L; /* letzte emfaenger adresse */
- static int lastadrfunktion = 0; /* letzte funktion der adresse */
- static char lastchar = '\0';
- static int lastbitpos = 0; /* letzte Frameposition */
- static int lastget = ADRESS; /* was fuer einen Typ hatte das
- letzte Frame ? */
-
- int i;
- unsigned long l;
-
-
- if ((frame&0x80000000) != 0L) i = 1; /* nachricht */
- else i = 0; /* adresse (nur Ton) */
- if (i == 0) { /* es ist ein adress
- frame */
-
- if (lastget == ADRESS && lastadrfunktion > 0 && \
- lastadress != 0) { /* der letzte war eine adresse also
- war er nurton */
-
- printf("\nA:%07ld | %s | T | BEEP", lastadress, asc_time);
- printf("%d", lastadrfunktion);
- #ifdef LOGFILE
- fprintf(logfile, "\nA:%07ld | %s | T | BEEP", lastadress, \
- asc_time);
- fprintf(logfile, "%d", lastadrfunktion);
- #endif
- }
-
- if (frame == SYNCRON) { /* das ist nur ein eingeschobenes
- Syncronwort */
- lastget = DATEN; /* wird nicht als adresse
- gewertet */
- } else if (frame == IDLE) { /* das ist nur ein Fuellwort */
- lastadress = 0L;
- lastadrfunktion = 0; /* alles zurueckstellen */
- lastbitpos = 0;
- lastget = ADRESS; /* ende einer Nachricht */
- } else { /* adressse + funktion merken */
- lastadress = ((frame>>10)&0x001FFFF8L)+(framepos/2);
- lastadrfunktion = ((frame >> 11)&0x00000003L)+1;
- lastbitpos = 0;
- lastget = ADRESS; /* dies war eine Adresse */
- }
- } else { /* es ist ein Daten frame */
-
- if (lastbitpos == 0) { /* wir sind am anfang eines
- Datenwortes */
- if (lastadrfunktion == 1) { /* numerikpager */
- printf("\nA:%07ld | %s | N | ", lastadress, asc_time);
- #ifdef LOGFILE
- fprintf(logfile, "\nA:%07ld | %s | N | ", lastadress, \
- asc_time);
- #endif
- } else if (lastadrfunktion == 4) { /* alphaPager */
- printf("\nA:%07ld | %s | A | ", lastadress, asc_time);
- #ifdef LOGFILE
- fprintf(logfile, "\nA:%07ld | %s | A | ", lastadress, \
- asc_time);
- #endif
- lastchar = '\0';
- }
- }
-
-
-
- /* Daten analysiern und ausgeben */
- frame <<= 1; /* das erste bit wurde schon
- interpretiert und wird jetzt
- ignoriert */
- i = 0;
- if (lastadrfunktion == 1) { /* numerik Pager decodieren */
- for (i = 0; i <= 4; i++) {
- l = frame&0xf0000000L; /* ich brauch nur die
- hoechsten vier bits */
- l >>= 28; /* bitte als char */
- printf("%c", numerik[(char)l]); /* so einer sind wir */
- #ifdef LOGFILE
- fprintf(logfile, "%c", numerik[(char)l]);
- #endif
- frame <<= 4;
- lastbitpos += 4;
- }
- }
- if (lastadrfunktion == 4) { /* alpha Pager decodieren */
- for (i = 0; i <= 19; i++) { /* alle 20 Bits nacheinader
- durchmachen */
- lastchar >>= 1;
- if ((frame&0x80000000L) != 0L) lastchar |= 0x40; /* bit in ein Char schieben */
- frame <<= 1;
- lastbitpos++;
- if ((lastbitpos%7) == 0) { /* ein neues Datenwort
- ist voll */
- printf("%c", lastchar);
- #ifdef LOGFILE
- fprintf(logfile, "%c", lastchar);
- #endif
- lastchar = '\0';
- }
- }
- }
- lastget = DATEN;
- }
- }
-
-
- void
- mach_hin(int baud) /* wir gehen auf emfang */
- {
- int i, j, k, anz, paritaet, timercl, timertic;
- unsigned long l;
- int getmodus;
- char old_0x21, old_pio_b;
- char c;
- time_t zeit;
- struct tm *zeit2;
-
- #ifdef LOGFILE
- logfile = fopen("logfile.txt", "a");
- if (logfile == NULL) return;
- #endif
-
-
- disable(); /* alle interrupts abschalten */
-
- roh_daten_anfang = roh_daten_ende = roh_daten_laenge = 0;
- getmodus = GETSYNCR;
- anz = k = 0;
- if (baud == 1200) {
- printf("1200 Baud\n");
- tics = TIMER0B1200;
- } else {
- printf("512 Baud\n");
- tics = TIMER0B512;
- }
- tics_2 = tics/2;
-
- old_vec = getvect(12); /* alte Timerserviceroutine retten */
- setvect(12, lauf_er); /* timerserviceroutine setzen */
-
- time_int = getvect(0x1c); /* timer0 interrupt setzen */
- setvect(0x1c, time_i);
-
- outportb(COMPORT+MCR, 0x09);/* Leitungen setzen */
- outportb(COMPORT+IER, 0x08);/* MODEMzustandswechsel */
-
- old_0x21 = inportb(0x21); /* interrupt maske holen */
- outportb(0x21, old_0x21&(char)(~((char)0x10))); /* Timer 2
- einschalten */
-
- outportb(0x43, 0xB0); /* Zaehler auf hoechsten wert stellen */
- outportb(0x42, 0xff);
- outportb(0x42, 0xff);
- old_pio_b = inportb(0x61); /* pio-b einlesen */
- outportb(0x61, old_pio_b|0x01); /* Zaehler einschalten */
-
- enable(); /* jetzt gehts los */
-
-
-
- do {
- if (abbruch) break;
-
-
- if (eine_sek_weg) { /* uhr nachstellen */
- eine_sek_weg = 0;
-
- if (kbhit() != 0) { /* ein Zeichen von der Tastatur
- liegt an also abbrechen */
- break;
- }
-
- time(&zeit);
- zeit2 = localtime(&zeit);
- strcpy(asc_time, strip_cr(asctime(zeit2))); /* neue uhrzeit */
-
- #ifdef LOGFILE
- if (last_sync >= 0) last_sync++;
- if (last_sync > 20) { /* 20 Sekunden lang kein Sync mehr
- gekommen */
- disable();
- if (logfile != NULL) fclose(logfile);
- logfile = fopen("logfile.txt", "a");
- if (logfile == NULL) {
- printf("Logfile laesst sich nicht oeffnen\n");
- abbruch = 1;
- }
- enable();
- last_sync = -1;
- }
- #endif
- }
-
-
- if (roh_daten_laenge > 0) { /* timerinterrupt hat ein oder
- mehr neue Zeichen eingelesen */
-
- /* felddaten holen */
- i = roh_daten_feld[roh_daten_anfang++];
- if (roh_daten_anfang > MAXARRAY) roh_daten_anfang = 0;
- roh_daten_laenge--;
- /*
- printf("%c", i+'0');
- fflush(stdout);
- */
- /* felddaten auswerten */
-
- if (getmodus == GETSYNCR) { /* Erstes Syncronframe
- erwarten */
- l <<= 1;
- if (i == 1) l |= 0x00000001L; /* bit setzen */
- if (l == SYNCRON || l == SYNCINFO) { /* wert stimmt
- mit Syncronwort
- ueberein */
- /* printf("\nSyncronwort");
- fflush(stdout); */
- last_sync = 0;
- getmodus = GETFRAME;
- anz = k = paritaet = 0;
- l = 0L;
- decode_frame(0, IDLE);
- }
- } else if (getmodus == GETFRAME) { /* GETFRAME Daten als
- Frame einlesen */
- anz++;
- l <<= 1;
- if (i == 1) {
- l |= 0x00000001L; /* bit setzen */
- if (paritaet == 0) paritaet = 1;
- else paritaet = 0;
- }
- if (anz >= 32) { /* neues Frame ist
- vollstaendig */
- if (paritaet == 1) {
- printf("%c", 247); /* paritaetsfehler */
- fflush(stdout);
- #ifdef BITWRONG
- l = 1L; /* fallback machen */
- getmodus = GETSYNCR;
- decode_frame(0, IDLE);
- anz = k = paritaet = 0;
- #endif
- }
- if (k >= 16 || l == SYNCRON || l == SYNCINFO) {
- /* egal was dies MUSS ein Syncronwort seien */
- decode_frame(0, SYNCRON);
- last_sync = 0;
- k = 0;
- } else if (l == IDLE) { /* nur idle keine
- relevanten daten */
- decode_frame(k, l);
- /* printf("IDLE\n"); */
- k++;
- } else { /* endlich ein
- normales Frame */
- decode_frame(k, l);
- k++;
- }
- anz = paritaet = 0;
- l = 0L;
- }
- }
- }
-
-
- } while(42); /* endlos */
-
-
-
- /* destall interrupts */
- disable();
- setvect(12, old_vec); /* timerserviceroutine zuruecksetzen */
- setvect(0x1c, time_int); /* alter Timer2 interrupt */
- outportb(0x21, old_0x21); /* alte Timer einschalten */
- outportb(0x61, old_pio_b); /* Zaehler Ursprung */
- enable();
- #ifdef LOGFILE
- if (logfile != NULL) fclose(logfile);
- #endif
- return;
- }
-
-
- void
- interrupt lauf_er() /* interrupt wenn wechsel an CTS
- verstrichene Zeit und Zustand
- feststellen, anzahl von 0/1 in
- puffer schreiben */
- {
- char bytein, c;
- unsigned int i;
- unsigned int j;
-
-
- bytein = inportb(COMPORT+MSR);
- if ((bytein&0x01) == 0x01) { /* CTS zustands wechselaufgetreten */
- c = ((bytein&0x10) != 0) ? (char)0 : (char)1; /* hab ich ne 0
- oder ne 1 */
- outportb(0x43, 0x80); /* Zaehlerstand auslesen */
- i = inportb(0x42);
- i += (256 * inportb(0x42));
- outportb(0x43, 0xB0); /* Zaehler auf hoechsten wert neustellen */
- outportb(0x42, 0xff);
- outportb(0x42, 0xff);
-
- i = 0xffff-i; /* wieviele Zaehlerschritte sind
- vergangen */
- j = i/tics; /* wieviele Bits waehren das ? */
- if (i%tics > tics_2) j++; /* ist vieleicht die Zeit
- unterlaufen worden? */
- /* if (j <= 0) j = 1; */
-
- for (i = 1; i <= j; i++) { /* anzahl der bits die decodiert
- wurden speichern */
- if (roh_daten_laenge < MAXARRAY) {
- roh_daten_feld[roh_daten_ende++] = c;
- if (roh_daten_ende > MAXARRAY) roh_daten_ende = 0;
- roh_daten_laenge++;
- } else printf("\nPufferueberlauf\n");
- }
- }
- outportb(0x20,0x20); /* end of interrupt klarmachen */
- }
-
-
- void interrupt time_i() /* wird 18.2/Sekunde aufgerufen */
- {
- static int t = 0;
-
- t++;
- if (t >= 19) { /* genuegend zeit vergangen ? */
- t = 0;
- eine_sek_weg = 1;
- }
- /* time_int(); */ /* alte zeitroutine weiter machen */
- }
-
-
-
- int
- main(int argc, char *argv[])
- {
- roh_daten_feld = (char *)malloc(MAXARRAY+300);
- if (roh_daten_feld == NULL) exit(0);
- printf("\nPOCSAC Decoder fuer COM1\n");
- printf("Als Argumente bitte die Baudrate eingeben (512/1200)\n");
- if (argc != 2) {
- printf("keine Baudrate\n");
- return(0);
- }
-
- mach_hin(atoi(argv[1]));
-
- free(roh_daten_feld);
- }
-
-