Subversion Repositories public

Rev

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