Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / lib / colonet_dragonfly / colonet_dragonfly.c @ 344

History | View | Annotate | Download (7.82 KB)

1 11 emarinel
/** @file colonet.c
2
 * @brief Colonet library for DRAGONFLY colony robots
3
 *
4
 * @author Eugene Marinelli
5 149 emarinel
 * @date 10/10/07
6
 *
7 11 emarinel
 * @bug Handler registration not tested
8
 * @bug Request reponding not implemented - only accepts commands.
9
 */
10
11 149 emarinel
#include <assert.h>
12 11 emarinel
#include <dragonfly_lib.h>
13 149 emarinel
#include <string.h>
14
#include <wireless.h>
15
16 11 emarinel
#include "colonet_dragonfly.h"
17
18
typedef struct {
19
  unsigned char msgId; //is this necessary?
20
  void (*handler)(void);
21
} UserHandler;
22
23
/* Globals (internal) */
24
static UserHandler user_handlers[USER_DEFINED_MSG_TOTAL];
25
26
/* Internal function prototypes */
27 125 emarinel
static void packet_string_to_struct(ColonetRobotServerPacket* dest_pkt,
28
                                    char* pkt_buf);
29 11 emarinel
static unsigned int two_bytes_to_int(char high, char low);
30 149 emarinel
static void colonet_handle_receive(char type, int source,
31
                                   unsigned char* packet, int length);
32 11 emarinel
33 149 emarinel
static PacketGroupHandler colonet_pgh;
34
35 11 emarinel
/* Public functions */
36 149 emarinel
int colonet_init() {
37
  colonet_pgh.groupCode = COLONET_PACKET_GROUP_ID;
38
  colonet_pgh.timeout_handler = NULL;
39
  colonet_pgh.handle_response = NULL;
40
  colonet_pgh.handle_receive = colonet_handle_receive;
41
  colonet_pgh.unregister = NULL;
42
43
  // TODO this should return an error if wl_init has not been called yet.
44
  wl_register_packet_group(&colonet_pgh);
45
46
  return 0;
47
}
48
49
/* Private functions */
50
51
/** @brief Handles colonet packets.  Should be called by parse_buffer
52
 * when it is determined that a colonet message has been received.
53
 *
54
 * @param robot_id The robot id
55
 * @param pkt_buf The packet buffer (e.g. wl_buf)
56
 *
57
 * @return -1 on error (invalid msgId), 0 on success
58
 */
59 307 emarinel
static void colonet_handle_receive(char type, int source, unsigned char* packet,
60
                                   int length) {
61 125 emarinel
  ColonetRobotServerPacket pkt;
62 11 emarinel
  unsigned char* args; //up to 7 char args
63
  unsigned int int_args[3]; //up to 3 int (2-byte) args
64
65 174 emarinel
  usb_puts("Packet received.\n");
66 175 emarinel
  char buf[40];
67
  sprintf(buf, "length=%d\n", length);
68
69
  int i;
70
  for (i = 0; i < length; i++) {
71
    sprintf(buf, "%d: %d ", i, packet[i]);
72
    usb_puts(buf);
73
  }
74
  usb_puts("\n");
75
76 174 emarinel
  //printf("received message from %d of length %d\n", source, length);
77 11 emarinel
78 174 emarinel
  ///assert(length == sizeof(ColonetRobotServerPacket));
79 149 emarinel
  packet_string_to_struct(&pkt, packet);
80 11 emarinel
81 175 emarinel
  char buf2[40];
82
  sprintf(buf2, "client_id:%d, msg_code:%d\n", pkt.client_id, pkt.msg_code);
83
  usb_puts(buf2);
84
85 11 emarinel
  args = pkt.data;
86 149 emarinel
87 11 emarinel
  int_args[0] = two_bytes_to_int(args[0], args[1]);
88
  int_args[1] = two_bytes_to_int(args[2], args[3]);
89
  int_args[2] = two_bytes_to_int(args[4], args[5]);
90
91 149 emarinel
  if (type == COLONET_REQUEST) {
92 175 emarinel
    usb_puts("type is colonet request\n");
93
94 11 emarinel
    /* TODO - send back data! */
95
96 149 emarinel
    switch (pkt.msg_code) {
97 11 emarinel
      //Sharp
98
    case READ_DISTANCE:
99
      break;
100
    case LINEARIZE_DISTANCE:
101
      break;
102
    case LOG_DISTANCE:
103
      break;
104
105
106
      //Analog
107
    case CALL_ANALOG8:
108
      break;
109
    case CALL_ANALOG10:
110
      break;
111
    case WHEEL:
112
      break;
113
    case BATTERY:
114 344 gtress
            wl_send_robot_to_robot_global_packet(colonet_pgh.groupCode, BATTERY,
115
                "brouhaha", 8, 0xA, 0);
116 11 emarinel
      break;
117
118
      //BOM
119
    case GETMAXBOM:
120
      break;
121
122
      //Dio
123
    case DIGITAL_INPUT:
124
      break;
125
    case BUTTON1_READ:
126
      break;
127
    case BUTTON2_READ:
128
      break;
129
130
      //Bumper
131
    case DETECT_BUMP:
132
      break;
133
    }
134 149 emarinel
  } else if (type == COLONET_COMMAND) {
135 175 emarinel
    usb_puts("type is colonet command...\n");
136 11 emarinel
137 175 emarinel
/* TODO uncomment this stuff */
138
/*     if (pkt.msg_code >= USER_DEFINED_MSG_ID_START && */
139
/*         pkt.msg_code <= USER_DEFINED_MSG_ID_END) { */
140
/*       if (user_handlers[pkt.msg_code - USER_DEFINED_MSG_ID_START].handler) { */
141
/*         /\* Call the user's handler function if it the function's address */
142
/*          * is non-zero (has been set) *\/ */
143
/*         user_handlers[pkt.msg_code - USER_DEFINED_MSG_ID_START].handler(); */
144
/*       } */
145
/*     } */
146 11 emarinel
147 175 emarinel
    switch (pkt.msg_code) {
148
/*     default: */
149
/*       printf("%s: Error - message code %d not implemented\n", __FUNCTION__, */
150
/*              pkt.msg_code); */
151
/*       break; */
152
153 11 emarinel
      //Buzzer
154
    case BUZZER_INIT:
155
      buzzer_init();
156
      break;
157
    case BUZZER_SET_VAL:
158
      buzzer_set_val(args[0]);
159
      break;
160
    case BUZZER_SET_FREQ:
161
      buzzer_set_freq(args[0]);
162
      break;
163
    case BUZZER_CHIRP:
164
      buzzer_chirp(int_args[0], int_args[1]);
165
      break;
166
    case BUZZER_OFF:
167
      buzzer_off();
168
      break;
169 149 emarinel
170 329 gtress
    // Battery
171
    case BATTERY:
172 334 gtress
      usb_puts("Got battery request.\n");
173
      int xbeeDongleID = 0xA;  // too bad this is hard-coded.
174
      char data[20];
175
      data[0] = 0;  // client ID specified in bytes 0-3
176
      data[1] = 0;
177
      data[2] = 0;
178
      data[3] = 0;
179
      data[4] = 0;  // ???
180
      data[5] = RESPONSE_TO_CLIENT_REQUEST;
181
      data[6] = ' ';
182
      data[7] = BATTERY;
183
      data[8] = ' ';
184
      data[9] = (char) wl_get_xbee_id();  // robot number (self)
185
      data[10] = ' ';
186
      data[11] = (char) battery8();  // battery reading
187
      data[12] = '\0';
188
189
      wl_send_robot_to_robot_global_packet(colonet_pgh.groupCode, COLONET_RESPONSE,
190
        data, 13, xbeeDongleID, 0);
191
      usb_puts("lol \n");
192
193 329 gtress
      break;
194
195 11 emarinel
    case ORB_INIT:
196
      orb_init();
197
      break;
198
      //Orb
199
    case ORB_SET:
200
      orb_set(args[0], args[1], args[2]);
201
      break;
202
    case ORB_SET_COLOR:
203
      orb_set_color(int_args[0]);
204
      break;
205
    case ORB_DISABLE:
206
      orb_disable();
207
      break;
208
    case ORB_ENABLE:
209
      orb_enable();
210
      break;
211
    case LED_INIT:
212
      break;
213
    case LED_USER:
214
      break;
215
    case ORB_SEND:
216
      //orb_send();
217
      break;
218
      //Motors
219
    case MOTORS_INIT:
220 175 emarinel
      usb_puts("calling motors_init\n");
221 11 emarinel
      motors_init();
222
      break;
223
    case MOTOR1_SET:
224 180 gtress
             sprintf(buf, "calling motor1_set [%i] [%i]\n", args[0], args[1]);
225
      usb_puts(buf);
226
      motor1_set(args[0], args[1]);
227 11 emarinel
      break;
228
    case MOTOR2_SET:
229 180 gtress
      sprintf(buf, "calling motor2_set [%i] [%i]\n", args[0], args[1]);
230
      usb_puts(buf);
231
      motor2_set(args[0], args[1]);
232 11 emarinel
      break;
233
    case MOTORS_OFF:
234 175 emarinel
      usb_puts("calling motors_off\n");
235 11 emarinel
      motors_off();
236
      break;
237
    case MOVE:
238 175 emarinel
      buf[40];
239 180 gtress
      sprintf(buf, "calling move with: %d, %d\n", args[0], args[1]);
240 175 emarinel
      usb_puts(buf);
241
      move(args[0], args[1]);
242 11 emarinel
      break;
243
    case XBEE_INIT:
244
      xbee_init();
245
      break;
246
247
    case XBEE_PUTC:
248
      xbee_putc((char)args[0]);
249
      break;
250
251
    case USB_INIT:
252
      usb_init();
253
      break;
254
255
    case USB_PUTC:
256
      usb_putc((char)args[0]);
257
      break;
258
259
    case PRINTF:
260
      printf("%s", pkt.data);
261
      break;
262
    case KILL_ROBOT:
263
      motors_off();
264
      buzzer_off();
265
      exit(0); //kill the robot
266
      break;
267
      //Time
268
    case DELAY_MS:
269
      delay_ms(int_args[0]);
270
      break;
271
272
      //Analog
273
    case ANALOG_INIT:
274 344 gtress
      //TODO: how do we really init the analog? this doesn't work:
275
      //analog_init();
276 11 emarinel
      break;
277
278
      //BOM
279
    case BOM_ON:
280
      bom_on();
281
      break;
282
    case BOM_OFF:
283
      bom_off();
284
      break;
285
286
      //Dio
287
    case DIGITAL_OUTPUT:
288
      digital_output(int_args[0], int_args[1]);
289
      break;
290
    }
291 149 emarinel
  } else {
292 175 emarinel
    sprintf(buf, "%s: Error: Invalid colonet message type", __FUNCTION__);
293
    usb_puts(buf);
294 11 emarinel
  }
295
}
296
297
/* colonet_add_message
298
 * Adds a user-defined message
299
 */
300 149 emarinel
int colonet_add_message(unsigned char msgId, void (*handler)(void)) {
301 11 emarinel
  if(msgId < USER_DEFINED_MSG_ID_START || msgId > USER_DEFINED_MSG_ID_END){
302
    return -1;
303
  }
304
305
  /* Register this function in the array */
306
  user_handlers[msgId-USER_DEFINED_MSG_ID_START].msgId = msgId;
307
  user_handlers[msgId-USER_DEFINED_MSG_ID_START].handler = handler;
308
309
  return 0;
310
}
311
312 125 emarinel
static void packet_string_to_struct(ColonetRobotServerPacket* dest_pkt,
313
                                    char* pkt_buf) {
314 149 emarinel
  memcpy(dest_pkt, pkt_buf, sizeof(ColonetRobotServerPacket));
315 11 emarinel
}
316
317
/* two_bytes_to_int(char a, char b)
318
 * Returns int of form [high][low]
319
 */
320 149 emarinel
static unsigned int two_bytes_to_int(char high, char low) {
321 11 emarinel
  return (((unsigned int)high)<<8) + (unsigned int)low;
322
}