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