acarsdec/getmesg.c

218 lines
3.8 KiB
C

/*
* Copyright (c) 2007 by Thierry Leconte (F4DWV)
*
* $Id: getmesg.c,v 1.3 2007/03/28 06:26:05 f4dwv Exp $
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "acarsdec.h"
#define SYN 0x16
#define SOH 0x01
struct mstat_s {
enum { HEADL, HEADF, BSYNC1, BSYNC2, SYN1, SYN2, SOH1, TXT, CRC1,
CRC2, END } state;
int ind;
unsigned short crc;
char txt[243];
} mstat[2];
/* CCITT 16 CRC */
#define POLY 0x1021
static void update_crc(unsigned short *crc, unsigned char ch)
{
unsigned char v;
unsigned int i;
unsigned short flag;
v = 1;
for (i = 0; i < 8; i++) {
flag = (*crc & 0x8000);
*crc = *crc << 1;
if (ch & v)
*crc = *crc + 1;
if (flag != 0)
*crc = *crc ^ POLY;
v = v << 1;
}
}
static int build_mesg(char *txt, int len, msg_t * msg)
{
int i, k;
char r;
/* remove special chars */
for (i = 0; i < len; i++) {
r = txt[i];
if (r < ' ' && r != 0x0d && r != 0x0a)
r = 0xa4;
txt[i] = r;
}
txt[i] = '\0';
/* fill msg struct */
k = 0;
msg->mode = txt[k];
k++;
for (i = 0; i < 7; i++, k++) {
msg->addr[i] = txt[k];
}
msg->addr[7] = '\0';
/* ACK/NAK */
msg->ack = txt[k];
k++;
msg->label[0] = txt[k];
k++;
msg->label[1] = txt[k];
k++;
msg->label[2] = '\0';
msg->bid = txt[k];
k++;
k++;
for (i = 0; i < 4; i++, k++) {
msg->no[i] = txt[k];
}
msg->no[4] = '\0';
for (i = 0; i < 6; i++, k++) {
msg->fid[i] = txt[k];
}
msg->fid[6] = '\0';
strcpy(msg->txt, &(txt[k]));
return 1;
}
void init_mesg(void)
{
mstat[0].state = mstat[1].state = HEADL;
}
int getmesg(unsigned char r, msg_t * msg, int ch)
{
struct mstat_s *st;
st = &(mstat[ch]);
do {
switch (st->state) {
case HEADL:
if (r == 0xff) {
st->state = HEADF;
return 8;
}
resetbits(ch);
return 8;
break;
case HEADF:
if (r != 0xff) {
int i;
unsigned char m;
for (i = 0, m = 1; i < 7; i++, m = m << 1) {
if (!(r & m))
break;
}
if (i < 2) {
st->state = HEADL;
break;
}
st->state = BSYNC1;
st->ind = 0;
if (i != 2)
return (i - 2);
break;
}
return 6;
case BSYNC1:
if (r != 0x80 + '+')
st->ind++;
st->state = BSYNC2;
return 8;
case BSYNC2:
if (r != '*')
st->ind++;
st->state = SYN1;
return 8;
case SYN1:
if (r != SYN)
st->ind++;
st->state = SYN2;
return 8;
case SYN2:
if (r != SYN)
st->ind++;
st->state = SOH1;
return 8;
case SOH1:
if (r != SOH)
st->ind++;
if (st->ind > 2) {
st->state = HEADL;
break;
}
st->state = TXT;
st->ind = 0;
st->crc = 0;
return 8;
case TXT:
update_crc(&st->crc, r);
r = r & 0x7f;
if (r == 0x03 || r == 0x17) {
st->state = CRC1;
return 8;
}
st->txt[st->ind] = r;
st->ind++;
if (st->ind > 243) {
st->state = HEADL;
break;
}
return 8;
case CRC1:
update_crc(&st->crc, r);
st->state = CRC2;
return 8;
case CRC2:
update_crc(&st->crc, r);
st->state = END;
return 8;
case END:
st->state = HEADL;
if (st->crc == 0) {
build_mesg(st->txt, st->ind, msg);
return 0;
}
return 8;
}
} while (1);
}