Subversion Repositories public

Rev

Rev 216 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 andreas 1
#include "config.h"
2
#include <time.h>
3
#include <string.h>
4
#include <errno.h>
5
#include "garmin.h"
6
 
7
 
8
int
9
get_run_track_lap_info ( garmin_data * run,
10
			 uint32 *      track_index,
11
			 uint32 *      first_lap_index,
12
			 uint32 *      last_lap_index )
13
{
14
  D1000 * d1000;
15
  D1009 * d1009;
16
  D1010 * d1010;
17
 
18
  int ok = 1;
19
 
246 andreas 20
  if (!run) return 0;
21
 
93 andreas 22
  switch ( run->type ) {
23
  case data_D1000:
24
    d1000            = run->data;
25
    *track_index     = d1000->track_index;
26
    *first_lap_index = d1000->first_lap_index;
27
    *last_lap_index  = d1000->last_lap_index;
28
    break;
29
  case data_D1009:
30
    d1009            = run->data;
31
    *track_index     = d1009->track_index;
32
    *first_lap_index = d1009->first_lap_index;
33
    *last_lap_index  = d1009->last_lap_index;
34
    break;
35
  case data_D1010:
36
    d1010            = run->data;
37
    *track_index     = d1010->track_index;
38
    *first_lap_index = d1010->first_lap_index;
39
    *last_lap_index  = d1010->last_lap_index;
40
    break;
41
  default:
216 andreas 42
    fprintf(stderr, "get_run_track_lap_info: run type %d invalid!\n",run->type);
93 andreas 43
    ok = 0;
44
    break;
45
  }
46
 
47
  return ok;
48
}
49
 
50
 
51
int
52
get_lap_index ( garmin_data * lap, uint32 * lap_index )
53
{
54
  D1001 * d1001;
55
  D1011 * d1011;
56
  D1015 * d1015;
57
 
58
  int ok = 1;
59
 
246 andreas 60
  if (!lap) return 0;
61
 
93 andreas 62
  switch ( lap->type ) {
63
  case data_D1001:
64
    d1001      = lap->data;
65
    *lap_index = d1001->index;
66
    break;
67
  case data_D1011:
68
    d1011      = lap->data;
69
    *lap_index = d1011->index;
70
    break;
71
  case data_D1015:
72
    d1015      = lap->data;
73
    *lap_index = d1015->index;
74
    break;
75
  default:
216 andreas 76
    fprintf(stderr, "get_lap_index: lap type %d invalid!\n",lap->type);
93 andreas 77
    ok = 0;
78
    break;
79
  }
80
 
81
  return ok;
82
}
83
 
84
 
85
int
86
get_lap_start_time ( garmin_data * lap, time_type * start_time )
87
{
88
  D1001 * d1001;
89
  D1011 * d1011;
90
  D1015 * d1015;
91
 
92
  int ok = 1;
93
 
246 andreas 94
  if (!lap) return 0;
95
 
93 andreas 96
  switch ( lap->type ) {
97
  case data_D1001:
98
    d1001       = lap->data;
99
    *start_time = d1001->start_time + TIME_OFFSET;
100
    break;
101
  case data_D1011:
102
    d1011       = lap->data;
103
    *start_time = d1011->start_time + TIME_OFFSET;
104
    break;
105
  case data_D1015:
106
    d1015       = lap->data;
107
    *start_time = d1015->start_time + TIME_OFFSET;
108
    break;
109
  default:
216 andreas 110
    fprintf(stderr, "get_lap_start_time: lap type %d invalid!\n",lap->type);
93 andreas 111
    ok = 0;
112
    break;
113
  }
114
 
115
  return ok;
116
}
117
 
118
 
119
garmin_data *
120
get_track ( garmin_list * points, uint32 trk_index )
121
{
122
  garmin_list_node * n;
123
  garmin_data *      track = NULL;
124
  D311 *             d311;
125
  int                done = 0;
126
 
127
  /* Look for a data_D311 with an index that matches. */
128
 
246 andreas 129
  if (!points) return NULL;
130
 
93 andreas 131
  for ( n = points->head; n != NULL; n = n->next ) {    
132
    if ( n->data != NULL ) {
133
      switch ( n->data->type ) {
134
      case data_D311:
135
	if ( track == NULL ) {
136
	  d311 = n->data->data;
137
	  if ( d311->index == trk_index ) {
138
	    track = garmin_alloc_data(data_Dlist);
139
	    garmin_list_append(track->data,n->data);
140
	  }
141
	} else {
142
	  /* We've reached the end of the track */
143
	  done = 1;
144
	}
145
	break;
146
      case data_D300:
147
      case data_D301:
148
      case data_D302:
149
      case data_D303:
150
      case data_D304:
151
	if ( track != NULL ) {
152
	  garmin_list_append(track->data,n->data);
153
	}
154
	break;
155
      default:
156
	printf("get_track: point type %d invalid!\n",n->data->type);
157
	break;
158
      }
159
    }
160
 
161
    if ( done != 0 ) break;
162
  }
163
 
164
  return track;
165
}
166
 
167
 
168
void
169
garmin_save_runs ( garmin_unit * garmin )
170
{
171
  garmin_data *       data;
172
  garmin_data *       data0;
173
  garmin_data *       data1;
174
  garmin_data *       data2;
175
  garmin_data *       rlaps;
176
  garmin_data *       rtracks;
177
  garmin_list *       runs   = NULL;
178
  garmin_list *       laps   = NULL;
179
  garmin_list *       tracks = NULL;
180
  garmin_data *       rlist;
181
  garmin_list_node *  n;
182
  garmin_list_node *  m;
183
  uint32              trk;
184
  uint32              f_lap;
185
  uint32              l_lap;
186
  uint32              l_idx;
187
  time_type           start;
188
  time_t              start_time;
189
  char                filename[BUFSIZ];
190
  char *              filedir = NULL;
191
  char                path[PATH_MAX];
192
  char                filepath[BUFSIZ];
193
  struct tm *         tbuf;
194
 
246 andreas 195
  if (!garmin) return;
196
 
93 andreas 197
  if ( (filedir = getenv("GARMIN_SAVE_RUNS")) != NULL ) {
198
    filedir = realpath(filedir,path);
199
    if ( filedir == NULL ) {
200
      printf("GARMIN_SAVE_RUNS: %s: %s\n",
201
	     getenv("GARMIN_SAVE_RUNS"),strerror(errno));
202
    }
203
  }
204
  if ( filedir == NULL ) {
205
    filedir = getcwd(path,sizeof(path));
206
  }
207
 
208
  printf("Extracting data from Garmin %s\n",
209
	 garmin->product.product_description);
210
  printf("Files will be saved in '%s'\n",filedir);
211
 
212
  if ( (data = garmin_get(garmin,GET_RUNS)) != NULL ) {
213
 
214
    /* 
215
       We should have a list with three elements:
216
 
217
       1) The runs (which identify the track and lap indices)
218
       2) The laps (which are related to the runs)
219
       3) The tracks (which are related to the runs)
220
    */
221
 
222
    data0 = garmin_list_data(data,0);
223
    data1 = garmin_list_data(data,1);
224
    data2 = garmin_list_data(data,2);
225
 
226
    if ( data0 != NULL && (runs   = data0->data) != NULL &&
227
	 data1 != NULL && (laps   = data1->data) != NULL &&
228
	 data2 != NULL && (tracks = data2->data) != NULL ) {
229
 
230
      /* Print some debug output if requested. */
231
 
232
      if ( garmin->verbose != 0 ) {
233
	for ( m = laps->head; m != NULL; m = m->next ) {
234
	  if ( get_lap_index(m->data,&l_idx) != 0 ) {
235
	    printf("[garmin] lap: index [%d]\n",l_idx);
236
	  } else {
237
	    printf("[garmin] lap: index [??]\n");
238
	  }
239
	}
240
      }
241
 
242
      /* For each run, get its laps and track points. */
243
 
244
      for ( n = runs->head; n != NULL; n = n->next ) {
245
	if ( get_run_track_lap_info(n->data,&trk,&f_lap,&l_lap) != 0 ) {
246
 
247
	  if ( garmin->verbose != 0 ) {
248
	    printf("[garmin] run: track [%d], laps [%d:%d]\n",trk,f_lap,l_lap);
249
	  }
250
 
251
	  start = 0;
252
 
253
	  /* Get the laps. */
254
 
255
	  rlaps = garmin_alloc_data(data_Dlist);
256
	  for ( m = laps->head; m != NULL; m = m->next ) {
257
	    if ( get_lap_index(m->data,&l_idx) != 0 ) {
258
	      if ( l_idx >= f_lap && l_idx <= l_lap ) {
259
		if ( garmin->verbose != 0 ) {
260
		  printf("[garmin] lap [%d] falls within laps [%d:%d]\n",
261
			 l_idx,f_lap,l_lap);
262
		}
263
 
264
		garmin_list_append(rlaps->data,m->data);
265
 
266
		if ( l_idx == f_lap ) {
267
		  get_lap_start_time(m->data,&start);
268
		  if ( garmin->verbose != 0 ) {
269
		    printf("[garmin] first lap [%d] has start time [%d]\n",
270
			   l_idx,(int)start);
271
		  }
272
		}
273
	      }
274
	    }
275
	  }
276
 
277
	  /* Get the track points. */
278
 
279
	  rtracks = get_track(tracks,trk);
280
 
281
	  /* Now make a three-element list for this run. */
282
 
283
	  rlist = garmin_alloc_data(data_Dlist);
284
	  garmin_list_append(rlist->data,n->data);
285
	  garmin_list_append(rlist->data,rlaps);
286
	  garmin_list_append(rlist->data,rtracks);
287
 
288
	  /* 
289
	     Determine the filename based on the start time of the first lap. 
290
	  */
291
 
292
	  if ( (start_time = start) != 0 ) {
293
	    tbuf = localtime(&start_time);
294
	    snprintf(filepath,sizeof(filepath)-1,"%s/%d/%02d",
295
		    filedir,tbuf->tm_year+1900,tbuf->tm_mon+1);
296
	    strftime(filename,sizeof(filename),"%Y%m%dT%H%M%S.gmn",tbuf);
297
 
298
	    /* Save rlist to the file. */
299
 
300
	    if ( garmin_save(rlist,filename,filepath) != 0 ) {
301
	      printf("Wrote:   %s/%s\n",filepath,filename);
302
	    } else {
303
	      printf("Skipped: %s/%s\n",filepath,filename);
304
	    }
305
	  } else {
306
	    printf("Start time of first lap not found!\n");
307
	  }
308
 
309
	  /* Free the temporary lists we were using. */
310
 
311
	  if ( rlaps != NULL ) {
312
	    garmin_free_list_only(rlaps->data);
313
	    free(rlaps);
314
	  }
315
 
316
	  if ( rtracks != NULL ) {
317
	    garmin_free_list_only(rtracks->data);
318
	    free(rtracks);
319
	  }
320
 
321
	  if ( rlist != NULL ) {
322
	    garmin_free_list_only(rlist->data);
323
	    free(rlist);
324
	  }
325
	}
326
      }
327
    } else {
328
      if ( data0 == NULL ) {
329
	printf("Toplevel data missing element 0 (runs)\n");
330
      } else if ( runs == NULL ) {
331
	printf("No runs extracted!\n");
332
      }
333
      if ( data1 == NULL ) {
334
	printf("Toplevel data missing element 1 (laps)\n");
335
      } else if ( laps == NULL ) {
336
	printf("No laps extracted!\n");
337
      }
338
      if ( data2 == NULL ) {
339
	printf("Toplevel data missing element 2 (tracks)\n");
340
      } else if ( tracks == NULL ) {
341
	printf("No tracks extracted!\n");
342
      }
343
    }
344
    garmin_free_data(data);
345
  } else {
346
    printf("Unable to extract any data!\n");
347
  }
348
}