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