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