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
/** @file colonet.c
2
 * @brief Colonet library for DRAGONFLY colony robots
3
 *
4
 * @author Eugene Marinelli
5
 * @date 10/10/07
6
 *
7
 * @bug Handler registration not tested
8
 * @bug Request reponding not implemented - only accepts commands.
9
 */
10

    
11
#include <assert.h>
12
#include <dragonfly_lib.h>
13
#include <string.h>
14
#include <wireless.h>
15

    
16
#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
static void packet_string_to_struct(ColonetRobotServerPacket* dest_pkt,
28
                                    char* pkt_buf);
29
static unsigned int two_bytes_to_int(char high, char low);
30
static void colonet_handle_receive(char type, int source,
31
                                   unsigned char* packet, int length);
32

    
33
static PacketGroupHandler colonet_pgh;
34

    
35
/* Public functions */
36
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
static void colonet_handle_receive(char type, int source, unsigned char* packet,
60
                                   int length) {
61
  ColonetRobotServerPacket pkt;
62
  unsigned char* args; //up to 7 char args
63
  unsigned int int_args[3]; //up to 3 int (2-byte) args
64

    
65
  usb_puts("Packet received.\n");
66
  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
  //printf("received message from %d of length %d\n", source, length);
77

    
78
  ///assert(length == sizeof(ColonetRobotServerPacket));
79
  packet_string_to_struct(&pkt, packet);
80

    
81
  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
  args = pkt.data;
86

    
87
  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
  if (type == COLONET_REQUEST) {
92
    usb_puts("type is colonet request\n");
93

    
94
    /* TODO - send back data! */
95

    
96
    switch (pkt.msg_code) {
97
      //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
            wl_send_robot_to_robot_global_packet(colonet_pgh.groupCode, BATTERY,
115
                "brouhaha", 8, 0xA, 0);
116
      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
  } else if (type == COLONET_COMMAND) {
135
    usb_puts("type is colonet command...\n");
136

    
137
/* 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

    
147
    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
      //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

    
170
    // Battery
171
    case BATTERY:
172
      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
      break;
194

    
195
    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
      usb_puts("calling motors_init\n");
221
      motors_init();
222
      break;
223
    case MOTOR1_SET:
224
             sprintf(buf, "calling motor1_set [%i] [%i]\n", args[0], args[1]);
225
      usb_puts(buf);
226
      motor1_set(args[0], args[1]);
227
      break;
228
    case MOTOR2_SET:
229
      sprintf(buf, "calling motor2_set [%i] [%i]\n", args[0], args[1]);
230
      usb_puts(buf);
231
      motor2_set(args[0], args[1]);
232
      break;
233
    case MOTORS_OFF:
234
      usb_puts("calling motors_off\n");
235
      motors_off();
236
      break;
237
    case MOVE:
238
      buf[40];
239
      sprintf(buf, "calling move with: %d, %d\n", args[0], args[1]);
240
      usb_puts(buf);
241
      move(args[0], args[1]);
242
      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
      //TODO: how do we really init the analog? this doesn't work:
275
      //analog_init();
276
      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
  } else {
292
    sprintf(buf, "%s: Error: Invalid colonet message type", __FUNCTION__);
293
    usb_puts(buf);
294
  }
295
}
296

    
297
/* colonet_add_message
298
 * Adds a user-defined message
299
 */
300
int colonet_add_message(unsigned char msgId, void (*handler)(void)) {
301
  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
static void packet_string_to_struct(ColonetRobotServerPacket* dest_pkt,
313
                                    char* pkt_buf) {
314
  memcpy(dest_pkt, pkt_buf, sizeof(ColonetRobotServerPacket));
315
}
316

    
317
/* two_bytes_to_int(char a, char b)
318
 * Returns int of form [high][low]
319
 */
320
static unsigned int two_bytes_to_int(char high, char low) {
321
  return (((unsigned int)high)<<8) + (unsigned int)low;
322
}