getmesg.c - acarsdec - an ACARS decoder
(HTM) git clone git://r-36.net/acarsdec
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) 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