Subversion Repositories public

Rev

Rev 136 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 andreas 1
#include "config.h"
2
#include "garmin.h"
3
 
4
 
5
/* 
6
   Check to see whether a command is supported by a Garmin unit based on its
7
   available command protocols.
8
*/
9
 
10
int
11
garmin_command_supported ( garmin_unit *    garmin,
12
			   garmin_command   cmd )
13
{
14
  int ret = 0;
15
 
16
  switch ( cmd ) {
17
  case Cmnd_Abort_Transfer:
18
  case Cmnd_Turn_Off_Pwr:
19
    ret = 1;
20
    break;
21
 
22
  case Cmnd_Transfer_Alm:
23
    ret = garmin->protocol.almanac;
24
    break;
25
 
26
  case Cmnd_Transfer_Prx:
27
    ret = garmin->protocol.waypoint.proximity;
28
    break;
29
 
30
  case Cmnd_Transfer_Rte:
31
    ret = garmin->protocol.route;
32
    break;
33
 
34
  case Cmnd_Transfer_Time:
35
    ret = garmin->protocol.date_time;
36
    break;
37
 
38
  case Cmnd_Transfer_Wpt:
39
    ret = garmin->protocol.waypoint.waypoint;
40
    break;
41
 
42
  case Cmnd_Transfer_Posn:
43
    ret = garmin->protocol.position;
44
    break;
45
 
46
  case Cmnd_Transfer_Trk:
47
    ret = garmin->protocol.track;
48
    break;
49
 
50
  case Cmnd_Start_Pvt_Data:
51
  case Cmnd_Stop_Pvt_Data:
52
    ret = garmin->protocol.pvt;
53
    break;
54
 
55
  case Cmnd_FlightBook_Transfer:
56
    ret = garmin->protocol.flightbook;
57
    break;
58
 
59
  case Cmnd_Transfer_Laps:
60
    ret = garmin->protocol.lap;
61
    break;
62
 
63
  case Cmnd_Transfer_Wpt_Cats:
64
    ret = garmin->protocol.waypoint.category;
65
    break;
66
 
67
  case Cmnd_Transfer_Runs:
68
    ret = garmin->protocol.run;
69
    break;
70
 
71
  case Cmnd_Transfer_Workouts:
72
    ret = garmin->protocol.workout.workout;
73
    break;
74
 
75
  case Cmnd_Transfer_Workout_Occurrences:
76
    ret = garmin->protocol.workout.occurrence;
77
    break;
78
 
79
  case Cmnd_Transfer_Fitness_User_Profile:
80
    ret = garmin->protocol.fitness;
81
    break;
82
 
83
  case Cmnd_Transfer_Workout_Limits:
84
    ret = garmin->protocol.workout.limits;
85
    break;
86
 
87
  case Cmnd_Transfer_Courses:
88
    ret = garmin->protocol.course.course;
89
    break;
90
 
91
  case Cmnd_Transfer_Course_Laps:
92
    ret = garmin->protocol.course.lap;
93
    break;
94
 
95
  case Cmnd_Transfer_Course_Points:
96
    ret = garmin->protocol.course.point;
97
    break;
98
 
99
  case Cmnd_Transfer_Course_Tracks:
100
    ret = garmin->protocol.course.track + garmin->protocol.track;
101
    break;
102
 
103
  case Cmnd_Transfer_Course_Limits:
104
    ret = garmin->protocol.course.limits;
105
    break;
106
 
107
  default: 
108
    break;
109
  }
110
 
111
  return ret;
112
}
113
 
114
 
115
/* 
116
   Convert a garmin_command to a command packet, returning 1 if the command
117
   is supported by the unit's command protocol and 0 if it isn't.
118
*/
119
 
120
int
121
garmin_make_command_packet ( garmin_unit *    garmin, 
122
			     garmin_command   cmd,
123
			     garmin_packet *  packet )
124
{
125
  int    r = 1;
126
  uint16 c = 0;
127
  uint16 p = 0;
128
  uint8  b[2];
129
 
130
  /* Determine the packet ID based on the link protocol. */
131
 
132
  switch ( garmin->protocol.link ) {
133
  case link_L001:           p = L001_Pid_Command_Data;                   break;
134
  case link_L002:           p = L002_Pid_Command_Data;                   break;
135
  default:                  r = 0;                                       break;
136
  }
137
 
138
  /* 
139
     Although it's obvious from the spec that L001 implies A010 and L002
140
     implies A011, this relationship is not explicit.  We have to determine
141
     the command ID based on the unit's stated command protocol.
142
  */
143
 
144
#define CMD_CASE(x,y) case Cmnd_##y: c = x##_Cmnd_##y; break
145
#define A010_CASE(x)  CMD_CASE(A010,x)
146
#define A011_CASE(x)  CMD_CASE(A011,x)
147
#define CMD_DEFAULT   default: r = 0; break
148
 
149
  switch ( garmin->protocol.command ) {
150
  case appl_A010:
151
    switch ( cmd ) {
152
      A010_CASE(Abort_Transfer);
153
      A010_CASE(Turn_Off_Pwr);
154
      A010_CASE(Start_Pvt_Data);
155
      A010_CASE(Stop_Pvt_Data);
156
      A010_CASE(Transfer_Alm);
157
      A010_CASE(Transfer_Posn);
158
      A010_CASE(Transfer_Prx);
159
      A010_CASE(Transfer_Rte);
160
      A010_CASE(Transfer_Time);
161
      A010_CASE(Transfer_Trk);
162
      A010_CASE(Transfer_Wpt);
163
      A010_CASE(FlightBook_Transfer);
164
      A010_CASE(Transfer_Laps);
165
      A010_CASE(Transfer_Wpt_Cats);
166
      A010_CASE(Transfer_Runs);
167
      A010_CASE(Transfer_Workouts);
168
      A010_CASE(Transfer_Workout_Occurrences);
169
      A010_CASE(Transfer_Fitness_User_Profile);
170
      A010_CASE(Transfer_Workout_Limits);
171
      A010_CASE(Transfer_Courses);
172
      A010_CASE(Transfer_Course_Laps);
173
      A010_CASE(Transfer_Course_Points);
174
      A010_CASE(Transfer_Course_Tracks);
175
      A010_CASE(Transfer_Course_Limits);
176
      CMD_DEFAULT;
177
    }
178
    break;
179
  case appl_A011:
180
    switch ( cmd ) {
181
      A011_CASE(Abort_Transfer);
182
      A011_CASE(Turn_Off_Pwr);
183
      A011_CASE(Transfer_Alm);
184
      A011_CASE(Transfer_Prx);
185
      A011_CASE(Transfer_Rte);
186
      A011_CASE(Transfer_Time);
187
      A011_CASE(Transfer_Wpt);
188
      CMD_DEFAULT;
189
    }
190
    break;
191
    CMD_DEFAULT;
192
  }
193
 
194
  /* 
195
     If the command is supported by the unit's command protocol, build the
196
     packet.
197
  */
198
 
199
  if ( r != 0 ) {
200
    put_uint16(b,c);
201
    garmin_packetize(packet,p,2,b);
202
  }
203
 
204
  return r;
205
}
206
 
207
 
208
/* Send a command */
209
 
210
int
211
garmin_send_command ( garmin_unit * garmin, garmin_command cmd )
212
{
213
  garmin_packet packet;
214
  int ret = 0;
215
 
216
  if ( garmin_command_supported(garmin,cmd) &&
217
       garmin_make_command_packet(garmin,cmd,&packet) ) {
218
    ret = garmin_write(garmin,&packet);
219
  } else {
220
    /* Error: command not supported */
221
 
222
    printf("Error: command %d not supported\n",cmd);
223
  }
224
 
225
  return ret;
226
}
227
 
228