home *** CD-ROM | disk | FTP | other *** search
- /*
- level1rx.c -- Level 1 synchronous receive routines
-
- Poor Man's Packet (PMP)
- Copyright (c) 1991 by Andrew C. Payne All Rights Reserved.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation without fee for NON-COMMERCIAL AMATEUR RADIO USE ONLY is hereby
- granted, provided that the above copyright notice appear in all copies.
- The author makes no representations about the suitability of this software
- for any purpose. It is provided "as is" without express or implied warranty.
-
- July, 1989
- Andrew C. Payne
- */
-
- /* ----- Includes ----- */
-
- #include <stdio.h>
- #include <alloc.h>
- #include <conio.h>
- #include <dos.h>
- #include "pmp.h"
- #include "ports.h"
-
- #define MAXRXQUEUE 20 /* max items in queue */
- #define MAXL1DSIZE 400 /* max size of level 1 data field */
-
- extern word timer(void);
- extern word waittrans(word from);
-
- /* ---- Local Variables ----- */
-
- static struct ax25_level1 *RXQueue[MAXRXQUEUE]; /* Receive queue */
- static int RXQSize; /* number of items in queue */
-
- /* ----- Subroutines ----- */
-
- /* RXCarrier()
- Returns TRUE if receive carrier detected.
- */
- int RXCarrier()
- {
- register byte x;
-
- x = inportb(CDPort) & CDBit;
- return CDLevel ? x : !x;
- }
-
- /* RXLevel1()
- Called whenever a RX carrier is detected, handles packet reception.
- Received packets are put in the receive queue.
-
- Returns the number of packets in the RXQueue.
- */
- int RXLevel1(void)
- {
- int j;
- word t1,t2; /* transition times */
- int gotsync; /* TRUE if we have gotten a flag */
- int bits; /* bit time */
- byte *p; /* pointer to RX buffer */
- byte c; /* current rec'd character */
- int b; /* bits in c */
- struct ax25_level1 *RXB; /* current RX buffer */
- int bitcount; /* count of bits received */
-
- t1 = timer(); /* current time */
- gotsync = FALSE; /* we have no flag */
- ShowTXRX(FALSE,TRUE); /* update screen status */
- bitcount = 0; /* start counting bits */
- disable(); /* no interruptions */
-
- restart:
- if(RXQSize >= MAXRXQUEUE) { /* is the RX Queue full? */
- RXQOverflow++; /* count overflows */
- enable(); /* re-enable interrupts */
- return RXQSize; /* abort */
- }
-
- RXB = RXQueue[RXQSize]; /* next queue entry */
- p = RXB->data; /* initialize */
- b = c = 0;
-
- while(RXCarrier()) {
-
- /* wait for next transition */
- t2 = waittrans(t1-20000);
- bits = (((t1 - t2) + 994) / BITTIME) - 1;
- bitcount += (bits + 1);
- t1 = t2;
-
- /* check for SYNC character */
- if(bits == 6) {
-
- /* if we've already got a sync, check for an incoming packet */
- if(gotsync) {
- if(p != RXB->data) {
- if(b == 1) { /* got one! */
- RXB->len = p - RXB->data;
- RXQSize++; /* add item */
- goto restart; /* do again */
- } else
- RXFrameErr++;
- }
- }
- gotsync = TRUE;
- b = c = 0;
-
- /* store bits in the incoming packet */
- } else if(bits >= 0 && bits < 6) {
- j = bits; /* store the bits in C */
- while(j--) {
- c >>= 1;
- b++;
- c |= 0x80;
- if(b == 8) {
- *p++ = c; /* store it */
- c = 0;
- b = 0;
- }
- }
- if(bits != 5) {
- c >>= 1;
- b++;
- if(b == 8) {
- *p++ = c; /* store it */
- c = 0;
- b = 0;
- }
- }
- } else /* some strange bit count */
- gotsync = FALSE;
-
- /* check for RX buffer overflow */
- if((p - RXB->data) > MAXL1DSIZE) { /* packet too long */
- RXBOverflow++;
- gotsync = FALSE;
- goto restart;
- }
- }
-
- /* lost carrier */
- enable(); /* interrupts allowed */
- ShowTXRX(FALSE,FALSE);
- ClockAdjust(bitcount); /* speed up clock */
- return RXQSize;
- }
-
- /* RXProcess()
- Processes the packets sitting in the level1 RX queue. Valid
- packets are handed up to the AX.25 routines.
- */
- void RXProcess(void)
- {
- int i;
-
- /* empty RX queue? */
- if(RXQSize == 0)
- return;
-
- /* process RXQueue items */
- for(i=0; i<RXQSize; i++) {
-
- /* if CRC is good, show & handle packet */
- if(CRCCheck(RXQueue[i])) {
- RXCount++;
- AX25Level2(RXQueue[i]); /* upcall */
- } else {
- RXCRCErr++;
- if(PassMode) {
- uprintf(BrightAttr,"~");
- AX25Level2(RXQueue[i]); /* upcall */
- }
- }
- }
-
- /* empty RX Queue */
- RXQSize = 0;
- }
-
- /* RXInit()
- Initialize the RX routines: allocate the level 1 receive buffers.
- */
- void RXInit()
- {
- int i;
-
- /* allocate the RX Queue */
- for(i=0; i<MAXRXQUEUE; i++) {
- if((RXQueue[i] = malloc(sizeof(struct ax25_level1) + MAXL1DSIZE))
- == NULL)
- OutOfMemory();
- }
-
-
- RXQSize = 0; /* empty queue */
- }