POCSAC-Decoder (Source)
Hier ist das ganze nochmal als echtes Source-File.
/*
** 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
#include
#include
#include
#include
#include
#include
#include
#include
/*
**
** 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);
}
|