1 /********************************************************************
2 ** @source JEEPS packet reading and acknowledging functions
3 **
4 ** @author Copyright (C) 1999 Alan Bleasby
5 ** @version 1.0
6 ** @modified Dec 28 1999 Alan Bleasby. First version
7 ** @modified Copyright (C) 2006 Robert Lipe
8 ** @@
9 **
10 ** This library is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU Library General Public
12 ** License as published by the Free Software Foundation; either
13 ** version 2 of the License, or (at your option) any later version.
14 **
15 ** This library is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ** Library General Public License for more details.
19 **
20 ** You should have received a copy of the GNU Library General Public
21 ** License along with this library; if not, write to the
22 ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ** Boston, MA  02111-1307, USA.
24 ********************************************************************/
25 #include "gps.h"
26 #include "gpsserial.h"
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <time.h>
30 #include <errno.h>
31 
32 
33 /* @func GPS_Time_Now ***********************************************
34 **
35 ** Get current time
36 **
37 ** @return [time_t] number of bytes read
38 **********************************************************************/
39 
GPS_Time_Now(void)40 time_t GPS_Time_Now(void)
41 {
42   time_t secs;
43 
44   if (time(&secs)==-1) {
45     perror("time");
46     GPS_Error("GPS_Time_Now: Error reading time");
47     gps_errno = HARDWARE_ERROR;
48     return 0;
49   }
50 
51   return secs;
52 }
53 
54 
55 
56 
57 
58 
59 
60 /* @func GPS_Serial_Packet_Read ***********************************************
61 **
62 ** Read a packet
63 **
64 ** @param [r] fd [int32] file descriptor
65 ** @param [w] packet [GPS_PPacket *] packet string
66 **
67 ** @return [int32] number of bytes read
68 **********************************************************************/
69 
GPS_Serial_Packet_Read(gpsdevh * fd,GPS_PPacket * packet)70 int32 GPS_Serial_Packet_Read(gpsdevh* fd, GPS_PPacket* packet)
71 {
72   time_t start;
73   int32  n;
74   int32  len;
75   UC     u;
76   int32  isDLE;
77   UC*     p;
78   int32  i;
79   UC     chk=0, chk_read;
80   const char* m1;
81   const char* m2;
82 
83   len = 0;
84   isDLE = gpsFalse;
85   p = (*packet)->data;
86 
87   start = GPS_Time_Now();
88   GPS_Diag("Rx Data:");
89   while (GPS_Time_Now() < start+GPS_TIME_OUT) {
90     if ((n=GPS_Serial_Chars_Ready(fd))) {
91       if (GPS_Serial_Read(fd,&u,1)==-1) {
92         perror("read");
93         GPS_Error("GPS_Packet_Read: Read error");
94         gps_errno = FRAMING_ERROR;
95         return 0;
96       }
97 
98       GPS_Diag("%02x ", u);
99 
100       if (!len) {
101         if (u != DLE) {
102           (void) fprintf(stderr,"GPS_Packet_Read: No DLE.  Data received, but probably not a garmin packet.\n");
103           (void) fflush(stderr);
104           return 0;
105         }
106         ++len;
107         continue;
108       }
109 
110       if (len==1) {
111         (*packet)->type = u;
112         ++len;
113         continue;
114       }
115 
116       if (u == DLE) {
117         if (isDLE) {
118           isDLE = gpsFalse;
119           continue;
120         }
121         isDLE = gpsTrue;
122       }
123 
124       if (len == 2) {
125         (*packet)->n = u;
126         len = -1;
127         continue;
128       }
129 
130       if (u == ETX)
131         if (isDLE) {
132           if (p-(*packet)->data-2 != (*packet)->n) {
133             GPS_Error("GPS_Packet_Read: Bad count");
134             gps_errno = FRAMING_ERROR;
135             return 0;
136           }
137           chk_read = *(p-2);
138 
139           for (i=0,p=(*packet)->data; i<(*packet)->n; ++i) {
140             chk -= *p++;
141           }
142           chk -= (*packet)->type;
143           chk -= (*packet)->n;
144           if (chk != chk_read) {
145             GPS_Error("CHECKSUM: Read error\n");
146             gps_errno = FRAMING_ERROR;
147             return 0;
148           }
149 
150           m1 = Get_Pkt_Type((*packet)->type, (*packet)->data[0], &m2);
151           if (gps_show_bytes) {
152             GPS_Diag(" ");
153             for (i = 0; i < (*packet)->n; i++) {
154               char c = (*packet)->data[i];
155               GPS_Diag("%c", isalnum(c) ? c  : '.');
156             }
157             GPS_Diag(" ");
158           }
159           GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : "");
160           return (*packet)->n;
161         }
162 
163       if (p - (*packet)->data >= MAX_GPS_PACKET_SIZE) {
164         GPS_Error("GPS_Serial_Packet_Read: Bad payload size/no ETX found");
165         gps_errno = FRAMING_ERROR;
166         return 0;
167       }
168       *p++ = u;
169     }
170   }
171 
172 
173   GPS_Error("GPS_Packet_Read: Timeout.  No data received.");
174   gps_errno = SERIAL_ERROR;
175 
176   return 0;
177 }
178 
179 
180 
181 /* @func GPS_Get_Ack *************************************************
182 **
183 ** Check that returned packet is an ack for the packet sent
184 **
185 ** @param [r] fd [int32] file descriptor
186 ** @param [r] tra [GPS_PPacket *] packet just transmitted
187 ** @param [r] rec [GPS_PPacket *] packet to receive
188 **
189 ** @return [int32] true if ACK
190 **********************************************************************/
191 
GPS_Serial_Get_Ack(gpsdevh * fd,GPS_PPacket * tra,GPS_PPacket * rec)192 int32 GPS_Serial_Get_Ack(gpsdevh* fd, GPS_PPacket* tra, GPS_PPacket* rec)
193 {
194   if (!GPS_Serial_Packet_Read(fd, rec)) {
195     return 0;
196   }
197 
198   if (LINK_ID[0].Pid_Ack_Byte != (*rec)->type) {
199     gps_error = FRAMING_ERROR;
200     /* rjl	return 0; */
201   }
202 
203   if (*(*rec)->data != (*tra)->type) {
204     gps_error = FRAMING_ERROR;
205     return 0;
206   }
207 
208   return 1;
209 }
210