1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 *
4 *
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <assert.h>
10 #include "aos/kernel.h"
11 #include <at/at.h>
12 #include "gps_parse.h"
13
14 typedef enum{
15 GPNON = 0x0000,
16 GPGGA = 0x0001,
17 GPGSA = 0x0002,
18 GPGSV = 0x0004,
19 GPRMC = 0x0008,
20 GPVTG = 0x0010
21 }en_gps_type;
22
23
24 typedef struct _gps_gpgga
25 {
26 char name[GPS_TYPE_NAME_LEN];
27 gps_time_t utc;
28 float lat;
29 char ns;
30 float lon;
31 char ew;
32 int sig;
33 int satinuse;
34 float HDOP;
35 float elv;
36 char elv_units;
37 float diff;
38 char diff_units;
39 float dgps_age;
40 int dgps_sid;
41 } gps_gpgga_t;
42
43 #define GPS_GPGGA_T_PARA_NUM (15)
44 typedef struct gps_inernel_data_stu{
45 gps_gpgga_t data_gga;
46
47 }gps_inernel_data_t;
48
49
50 gps_inernel_data_t g_gpsvalue;
51 int g_gpstypebitmap = GPGGA;
52
gps_gpgga_para_set(test_gps_data_t gpgga_index[],gps_gpgga_t * gpgga_para)53 static void gps_gpgga_para_set(test_gps_data_t gpgga_index[], gps_gpgga_t* gpgga_para)
54 {
55 gpgga_index[0].type = GPS_TYPE_STR;
56 gpgga_index[0].addr = &(gpgga_para->name[0]);
57 gpgga_index[1].type = GPS_TYPE_UTC;
58 gpgga_index[1].addr = &(gpgga_para->utc);
59
60 gpgga_index[2].type = GPS_TYPE_FLOAT;
61 gpgga_index[2].addr = &(gpgga_para->lat);
62 gpgga_index[3].type = GPS_TYPE_UINT8;
63 gpgga_index[3].addr = &(gpgga_para->ns);
64 gpgga_index[4].type = GPS_TYPE_FLOAT;
65 gpgga_index[4].addr = &(gpgga_para->lon);
66 gpgga_index[5].type = GPS_TYPE_UINT8;
67 gpgga_index[5].addr = &(gpgga_para->ew);
68
69 gpgga_index[6].type = GPS_TYPE_INT32;
70 gpgga_index[6].addr = &(gpgga_para->sig);
71 gpgga_index[7].type = GPS_TYPE_INT32;
72 gpgga_index[7].addr = &(gpgga_para->satinuse);
73 gpgga_index[8].type = GPS_TYPE_FLOAT;
74 gpgga_index[8].addr = &(gpgga_para->HDOP);
75 gpgga_index[9].type = GPS_TYPE_FLOAT;
76 gpgga_index[9].addr = &(gpgga_para->elv);
77
78 gpgga_index[10].type = GPS_TYPE_UINT8;
79 gpgga_index[10].addr = &(gpgga_para->elv_units);
80 gpgga_index[11].type = GPS_TYPE_FLOAT;
81 gpgga_index[11].addr = &(gpgga_para->diff);
82 gpgga_index[12].type = GPS_TYPE_UINT8;
83 gpgga_index[12].addr = &(gpgga_para->diff_units);
84 gpgga_index[13].type = GPS_TYPE_FLOAT;
85 gpgga_index[13].addr = &(gpgga_para->dgps_age);
86
87 gpgga_index[14].type = GPS_TYPE_INT32;
88 gpgga_index[14].addr = &(gpgga_para->dgps_sid);
89
90 }
91
92
gps_gpgga_data_parse(char * str,int len,gps_gpgga_t * result)93 static int gps_gpgga_data_parse(char *str, int len, gps_gpgga_t *result)
94 {
95 int i = 0;
96 char data[GPS_RCV_DATA_LEN];
97 char* prt0;
98 char* prt1 = &data[0];
99 test_gps_data_t gga_idx[GPS_GPGGA_T_PARA_NUM];
100
101 if((NULL == str) || (0 == result)){
102 return -1;
103 }
104
105 memcpy(data,str,len);
106 data[len] = '\0';
107
108 memset(result, 0, sizeof(gps_gpgga_t));
109 gps_gpgga_para_set(gga_idx,result);
110
111 for( i = 0; (i < 13) &&(NULL!=prt0); i++){
112 //printf("strlen(prt1) == %d\n",strlen(prt1));
113
114 prt0 = gps_strtok(prt1,&prt1,',',strlen(prt1));
115 //printf("prt0 == %s\n",prt0);
116
117 gps_data_conv(prt0,strlen(prt0),gga_idx[i].addr,gga_idx[i].type);
118 //printf("index %d\n\n",i);
119 }
120
121 prt0 = gps_strtok(prt1,&prt1,',',strlen(prt1));
122 gps_data_conv(prt0,strlen(prt0),gga_idx[i].addr,gga_idx[i].type);
123 i++;
124 //printf("index %d\n\n\n",i);
125
126 prt0 = gps_strtok(prt1,&prt1,'*',strlen(prt1));
127 gps_data_conv(prt0,strlen(prt0),gga_idx[i].addr,gga_idx[i].type);
128 //printf("index %d\n\n\n",i);
129
130 //printf("time %2d:%2d:%2d.%d\n",result->utc.hour,result->utc.min,result->utc.sec,result->utc.hsec);
131
132 return 0;
133 }
134
135
136
gps_gpgga_data_get(gps_gpgga_t * result,gps_data_t * pgpsdata)137 static int gps_gpgga_data_get(gps_gpgga_t *result,gps_data_t* pgpsdata)
138 {
139
140 if((NULL == result) || (0 == pgpsdata)){
141 return -1;
142 }
143
144 pgpsdata->utc.year = result->utc.year;
145 pgpsdata->utc.mon = result->utc.mon;
146 pgpsdata->utc.day = result->utc.day;
147 pgpsdata->utc.hour = result->utc.hour;
148 pgpsdata->utc.min = result->utc.min;
149 pgpsdata->utc.sec = result->utc.sec;
150 pgpsdata->utc.hsec = result->utc.hsec;
151
152 pgpsdata->lat = ('N' == result->ns)? result->lat : -(result->lat);
153 pgpsdata->lat = pgpsdata->lat/100;
154 pgpsdata->lon = ('E' == result->ew)? result->lon : -(result->lon);
155 pgpsdata->lon = pgpsdata->lon/100;
156 pgpsdata->elv = result->elv;
157
158 return 0;
159 }
160
161
162
gps_gp_type_get(const char * buf,int size)163 int gps_gp_type_get(const char *buf, int size)
164 {
165 static const char *pheads[] = {
166 "GPGGA",
167 "GPGSA",
168 "GPGSV",
169 "GPRMC",
170 "GPVTG"
171 };
172
173 if(0 == buf){
174 return -1;
175 }
176
177 if(size < 5)
178 return GPNON;
179 else if(0 == memcmp(buf, pheads[0], 5))
180 return GPGGA;
181 else if(0 == memcmp(buf, pheads[1], 5))
182 return GPGSA;
183 else if(0 == memcmp(buf, pheads[2], 5))
184 return GPGSV;
185 else if(0 == memcmp(buf, pheads[3], 5))
186 return GPRMC;
187 else if(0 == memcmp(buf, pheads[4], 5))
188 return GPVTG;
189
190 return GPNON;
191 }
192
gps_gp_type_filter(const char * buf,int size)193 bool gps_gp_type_filter(const char *buf, int size)
194 {
195 int ret = gps_gp_type_get(buf,size);
196
197 return (g_gpstypebitmap&ret) ? 1:0;
198 }
199
200
gps_gp_parse(char * str,int len,gps_data_t * pgpsdata)201 static int gps_gp_parse(char* str, int len, gps_data_t* pgpsdata)
202 {
203 int ret;
204 int ptype;
205
206 ptype = gps_gp_type_get(str+1,len-1);
207
208 switch(ptype){
209 case GPGGA:{
210 ret = gps_gpgga_data_parse(str, len,&(g_gpsvalue.data_gga));
211 if(0 != ret){
212 return -1;
213 }
214
215 ret = gps_gpgga_data_get(&(g_gpsvalue.data_gga), pgpsdata);
216 if(0 != ret){
217 return -1;
218 }
219
220 break;
221 }
222 default:
223 break;
224 }
225
226 return 0;
227 }
228
gps_gp_check(char * str,int len)229 static int gps_gp_check(char* str, int len)
230 {
231 int i;
232 int crc_calc = 0;
233 int crc = 0;
234 char* str_tmp = str;
235
236 if(str_tmp[0] != '$'){
237 return -1;
238 }
239
240 str_tmp++;
241
242 for(i = 1; (i < len) && (*str_tmp != '*'); i++,str_tmp++){
243 crc_calc ^= (int)(*str_tmp);
244 }
245
246 crc = gps_atoi(&str_tmp[1],2,16);
247 if(crc != crc_calc){
248 LOG("crc_origin == 0x%08x, crc_calc == 0x%08x\n",crc,crc_calc);
249 return -1;
250 }
251
252 return 0;
253 }
254
gps_gp_proc(const char * str,gps_data_t * pgpsdata)255 int gps_gp_proc(const char* str, gps_data_t* pgpsdata)
256 {
257 int ret;
258 int len;
259 char gpsdata[GPS_CALC_BUF_LEN];
260
261 if(0 == str){
262 return -1;
263 }
264
265 if(0 == pgpsdata){
266 return -1;
267 }
268
269 len = strlen(str);
270 if(len >= GPS_RCV_DATA_LEN){
271 return -1;
272 }
273
274 memcpy(&gpsdata[0], str, len);
275 gpsdata[len] = '\0';
276
277
278 ret = gps_gp_check(&gpsdata[0],len);
279 if(0 != ret){
280 return -1;
281 }
282
283 ret = gps_gp_parse(&gpsdata[0],len, pgpsdata);
284 if(0 != ret){
285 return -1;
286 }
287
288 return 0;
289 }
290
291
292
293