1 /***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: NMEA0183 Support Classes
5 * Author: Samuel R. Blackburn, David S. Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2010 by Samuel R. Blackburn, David S Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program 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 *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 ***************************************************************************
25 *
26 * S Blackburn's original source license: *
27 * "You can use it any way you like." *
28 * More recent (2010) license statement: *
29 * "It is BSD license, do with it what you will" *
30 */
31
32
33 #include "nmea0183.h"
34 //#pragma hdrstop
35
36 /*
37 ** Author: Samuel R. Blackburn
38 ** CI$: 76300,326
39 ** Internet: sammy@sed.csc.com
40 **
41 ** You can use it any way you like.
42 */
43
44 //IMPLEMENT_DYNAMIC( GLL, RESPONSE )
45
GLL()46 GLL::GLL()
47 {
48 Mnemonic = _T("GLL");
49 Empty();
50 }
51
~GLL()52 GLL::~GLL()
53 {
54 Mnemonic.Empty();
55 Empty();
56 }
57
Empty(void)58 void GLL::Empty( void )
59 {
60 // ASSERT_VALID( this );
61
62 Position.Empty();
63 UTCTime.Empty();
64 IsDataValid = Unknown0183;
65 }
66
Parse(const SENTENCE & sentence)67 bool GLL::Parse( const SENTENCE& sentence )
68 {
69 // ASSERT_VALID( this );
70
71 /*
72 ** GLL - Geographic Position - Latitude/Longitude
73 ** Latitude, N/S, Longitude, E/W, UTC, Status
74 **
75 ** +-------------------------------- 1) Latitude
76 ** | +------------------------ 2) N or S (North or South)
77 ** | | +---------------------- 3) Longitude
78 ** | | | +------------- 4) E or W (East or West)
79 ** | | | | +----------- 5) Universal Time Coordinated (UTC)
80 ** | | | | | +- 6) Status A - Data Valid, V - Data Invalid
81 ** | | | | | | +7) Checksum
82 ** $--GLL,llll.ll,a,yyyyy.yy,a,hhmmss.ss,A*hh<CR><LF>
83 */
84
85 /*
86 ** First we check the checksum...
87 */
88
89 int target_field_count = 6;
90
91 NMEA0183_BOOLEAN check = sentence.IsChecksumBad( 7 );
92
93 if ( check == NTrue )
94 {
95
96 /*
97 ** This may be an NMEA Version 2.3 sentence, with "Mode" field
98 */
99 wxString checksum_in_sentence = sentence.Field( 7 );
100 if(checksum_in_sentence.StartsWith(_T("*"))) // Field is a valid erroneous checksum
101 {
102 SetErrorMessage( _T("Invalid Checksum") );
103 return( FALSE );
104 }
105
106 else
107 {
108 target_field_count = 7;
109 check = sentence.IsChecksumBad( 8 );
110 if( check == NTrue)
111 {
112 SetErrorMessage( _T("Invalid Checksum") );
113 return( FALSE );
114 }
115 }
116 }
117
118
119 if ( sentence.GetNumberOfDataFields() == target_field_count )
120 {
121 Position.Parse( 1, 2, 3, 4, sentence );
122 UTCTime = sentence.Field( 5 );
123 IsDataValid = sentence.Boolean( 6 );
124
125 return( TRUE );
126 }
127
128 // May be old style GLL sentence
129 if ( sentence.GetNumberOfDataFields() == 4 )
130 {
131 Position.Parse( 1, 2, 3, 4, sentence );
132 IsDataValid = NTrue;
133
134 return( TRUE );
135 }
136
137 // A real error...
138 SetErrorMessage( _T("Invalid FieldCount") );
139 return( FALSE );
140 }
141
142
PlainEnglish(void)143 const wxString& GLL::PlainEnglish( void )
144 {
145 // ASSERT_VALID( this );
146
147 static wxString return_string;
148
149 return_string.Empty();
150 /*
151 char temp_string[ 128 ];
152
153 sprintf( temp_string, "At %d, you were at Latitude %ld %s, Longitude %ld %s.",
154 (const char *) UTCTime,
155 Position.Latitude.Latitude,
156 ( Position.Latitude.Northing == North ) ? "North" : "South",
157 Position.Longitude.Longitude,
158 ( Position.Longitude.Easting == East ) ? "East" : "West" );
159
160 return_string = temp_string;
161 */
162 return( return_string );
163 }
164
165
Write(SENTENCE & sentence)166 bool GLL::Write( SENTENCE& sentence )
167 {
168 // ASSERT_VALID( this );
169
170 /*
171 ** Let the parent do its thing
172 */
173
174 RESPONSE::Write( sentence );
175
176 sentence += Position;
177 sentence += UTCTime;
178 sentence += IsDataValid;
179
180 sentence.Finish();
181
182 return( TRUE );
183 }
184
operator =(const GLL & source)185 const GLL& GLL::operator = ( const GLL& source )
186 {
187 // ASSERT_VALID( this );
188
189 Position = source.Position;
190 UTCTime = source.UTCTime;
191 IsDataValid = source.IsDataValid;
192
193 return( *this );
194 }
195