[Chaos CD]
[Datenschleuder] [41]    POCSAC-Decoder (Source)
[Gescannte Version] [ -- ] [ ++ ] [Suchen]  

 

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);
}

 

  [Chaos CD]
[Datenschleuder] [41]    POCSAC-Decoder (Source)
[Gescannte Version] [ -- ] [ ++ ] [Suchen]