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