acarsdec

an ACARS decoder
git clone git://r-36.net/acarsdec
Log | Files | Refs | README

getmesg.c (3934B)


      1 /*
      2  *  Copyright (c) 2007 by Thierry Leconte (F4DWV)
      3  *
      4  *      $Id: getmesg.c,v 1.3 2007/03/28 06:26:05 f4dwv Exp $
      5  *
      6  *   This code is free software; you can redistribute it and/or modify
      7  *   it under the terms of the GNU Library General Public License version 2
      8  *   published by the Free Software Foundation.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *   GNU Library General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU Library General Public
     16  *   License along with this library; if not, write to the Free Software
     17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  *
     19  */
     20 
     21 #include <stdlib.h>
     22 #include <stdio.h>
     23 #include <string.h>
     24 
     25 #include "acarsdec.h"
     26 
     27 #define SYN 0x16
     28 #define SOH 0x01
     29 struct mstat_s {
     30 	enum { HEADL, HEADF, BSYNC1, BSYNC2, SYN1, SYN2, SOH1, TXT, CRC1,
     31 		    CRC2, END } state;
     32 	int ind;
     33 	unsigned short crc;
     34 	char txt[243+1];
     35 } mstat[2];
     36 
     37 
     38 /* CCITT 16 CRC */
     39 #define POLY 0x1021
     40 static void update_crc(unsigned short *crc, unsigned char ch)
     41 {
     42 	unsigned char v;
     43 	unsigned int i;
     44 	unsigned short flag;
     45 
     46 	v = 1;
     47 	for (i = 0; i < 8; i++) {
     48 		flag = (*crc & 0x8000);
     49 		*crc = *crc << 1;
     50 
     51 		if (ch & v)
     52 			*crc = *crc + 1;
     53 
     54 		if (flag != 0)
     55 			*crc = *crc ^ POLY;
     56 
     57 		v = v << 1;
     58 	}
     59 }
     60 
     61 static int build_mesg(char *txt, int len, msg_t *msg)
     62 {
     63 	int i, k;
     64 
     65 	/* fill msg struct */
     66 	k = 0;
     67 	msg->mode = txt[k];
     68 	k++;
     69 
     70 	for (i = 0; i < 7; i++, k++) {
     71 		msg->addr[i] = txt[k];
     72 	}
     73 	msg->addr[7] = '\0';
     74 
     75 	/* ACK/NAK */
     76 	msg->ack = txt[k];
     77 	k++;
     78 
     79 	msg->label[0] = txt[k];
     80 	k++;
     81 	msg->label[1] = txt[k];
     82 	k++;
     83 	msg->label[2] = '\0';
     84 
     85 	msg->bid = txt[k];
     86 	k++;
     87 
     88 	k++;
     89 
     90 	for (i = 0; i < 4; i++, k++) {
     91 		msg->no[i] = txt[k];
     92 	}
     93 	msg->no[4] = '\0';
     94 
     95 	for (i = 0; i < 6; i++, k++) {
     96 		msg->fid[i] = txt[k];
     97 	}
     98 	msg->fid[6] = '\0';
     99 
    100 	len -= k;
    101 	memmove(msg->txt, &(txt[k]), len);
    102 	msg->txt[len] = '\0';
    103 	msg->txtlen = len;
    104 
    105 	return 1;
    106 }
    107 
    108 void init_mesg(void)
    109 {
    110 	mstat[0].state = mstat[1].state = HEADL;
    111 }
    112 
    113 void
    114 print_mstat(struct mstat_s *mstat)
    115 {
    116 	if(mstat->state > 0) {
    117 		fprintf(stderr, "mstat: state = %d; ind = %d; crc = %.4x\n",
    118 				mstat->state, mstat->ind, mstat->crc);
    119 	}
    120 }
    121 
    122 int getmesg(unsigned char r, msg_t *msg, int ch)
    123 {
    124 	struct mstat_s *st;
    125 
    126 	st = &(mstat[ch]);
    127 
    128 	//print_mstat(st);
    129 
    130 	do {
    131 		switch (st->state) {
    132 		case HEADL:
    133 			if (r == 0xff) {
    134 				st->state = HEADF;
    135 				return 8;
    136 			}
    137 			resetbits(ch);
    138 			return 8;
    139 			break;
    140 		case HEADF:
    141 			if (r != 0xff) {
    142 				int i;
    143 				unsigned char m;
    144 
    145 				for (i = 0, m = 1; i < 7; i++, m = m << 1) {
    146 					if (!(r & m))
    147 						break;
    148 				}
    149 				if (i < 2) {
    150 					st->state = HEADL;
    151 					break;
    152 				}
    153 				st->state = BSYNC1;
    154 				st->ind = 0;
    155 				if (i != 2)
    156 					return (i - 2);
    157 				break;
    158 			}
    159 			return 6;
    160 		case BSYNC1:
    161 			if (r != 0x80 + '+')
    162 				st->ind++;
    163 			st->state = BSYNC2;
    164 			return 8;
    165 		case BSYNC2:
    166 			if (r != '*')
    167 				st->ind++;
    168 			st->state = SYN1;
    169 			return 8;
    170 		case SYN1:
    171 			if (r != SYN)
    172 				st->ind++;
    173 			st->state = SYN2;
    174 			return 8;
    175 		case SYN2:
    176 			if (r != SYN)
    177 				st->ind++;
    178 			st->state = SOH1;
    179 			return 8;
    180 		case SOH1:
    181 			if (r != SOH)
    182 				st->ind++;
    183 			if (st->ind > 2) {
    184 				st->state = HEADL;
    185 				break;
    186 			}
    187 			st->state = TXT;
    188 			st->ind = 0;
    189 			st->crc = 0;
    190 			return 8;
    191 		case TXT:
    192 			update_crc(&st->crc, r);
    193 			r = r & 0x7f;
    194 			if (r == 0x03 || r == 0x17) {
    195 				st->state = CRC1;
    196 				return 8;
    197 			}
    198 			st->txt[st->ind] = r;
    199 			st->ind++;
    200 			if (st->ind > 243) {
    201 				st->state = HEADL;
    202 				break;
    203 			}
    204 			return 8;
    205 		case CRC1:
    206 			update_crc(&st->crc, r);
    207 			st->state = CRC2;
    208 			return 8;
    209 		case CRC2:
    210 			update_crc(&st->crc, r);
    211 			st->state = END;
    212 			return 8;
    213 		case END:
    214 			st->state = HEADL;
    215 			if (st->crc == 0) {
    216 				build_mesg(st->txt, st->ind, msg);
    217 				return 0;
    218 			}
    219 			return 8;
    220 		}
    221 	} while (1);
    222 }
    223