Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / lib / colonet_wireless / colonet_wireless.cpp @ 175

History | View | Annotate | Download (5.04 KB)

1
/** @file colonet_wireless.c
2
 *
3
 * @brief Implementation of server-side colonet wireless library
4
 *
5
 * @author Eugene Marinelli
6
 */
7

    
8
/********************************* Includes **********************************/
9
#include <string>
10
#include <pthread.h>
11
#include <iostream>
12
#include <fstream>
13
#include <unistd.h>
14
#include <fcntl.h>
15

    
16
#include <wireless.h> // Colonet wireless library.
17

    
18
#include "colonet_defs.h"
19
#include "colonet_wireless.h"
20

    
21
/******************************* Definitions *********************************/
22

    
23
//Enable debug printouts
24
#define DEBUG 1
25

    
26
#ifdef DEBUG
27
#define dbg_printf(...) printf(__VA_ARGS__)
28
#define dbg_fprintf(...) fprintf(__VA_ARGS__)
29
#else
30
#define dbg_printf(...)
31
#define dbg_fprintf(...)
32
#endif
33

    
34
static MsgHandlerFunction message_handler;
35
static bool logging_enabled;
36
static char log_filename[80];
37
static pthread_t listener_thread;
38
static char wl_port[40];
39

    
40
/************************* Internal prototypes *******************************/
41
static void* listen(void* args);
42
static void timeout_handler(void);
43
static void handle_response(int frame, int received);
44
static void handle_receive(char type, int source, unsigned char* packet,
45
                           int len);
46
static void unregister(void);
47
static int log_packet(unsigned char* packet, int len);
48

    
49

    
50
/**************************** Public functions *******************************/
51
void colonet_wl_init(char* wl_port_, MsgHandlerFunction message_handler_,
52
                     char* log_filename_) {
53
  if (log_filename) {
54
    logging_enabled = true;
55
    sprintf(log_filename, log_filename_);
56
  }
57

    
58
  strncpy(wl_port, wl_port_, 40);
59

    
60
  // todo - initialize wireless port
61

    
62
  message_handler = message_handler_;
63
}
64

    
65
void colonet_wl_kill_listener_thread() {
66
  pthread_kill(listener_thread, 9);
67
}
68

    
69
int colonet_wl_run_listener_thread() {
70
  dbg_printf("Spawning listener thread...\n");
71

    
72
  if (pthread_create(&listener_thread, NULL, listen, NULL)) {
73
    perror("pthread_create");
74
    return -1;
75
  }
76

    
77
  return 0;
78
}
79

    
80
void colonet_wl_send(short client_source, short dest,
81
                     ColonetMessageType msg_type, unsigned char msg_code,
82
                     unsigned char* args) {
83
  printf("colonet_wl_send: client_source:%d, dest:%d, msg_code:%d\n",
84
         client_source, dest, msg_code);
85

    
86
  ColonetRobotServerPacket pkt;
87
  pkt.client_id = client_source;
88
  pkt.msg_code = msg_code;
89

    
90
  for (int i = 0; i < PACKET_DATA_LEN; i++) {
91
    pkt.data[i] = args[i];
92
  }
93

    
94
  if (dest == GLOBAL_DEST) {
95
    printf("sending to global dest\n");
96

    
97
    wl_send_global_packet(COLONET_PACKET_GROUP_ID, (char)msg_type,
98
                          (char*)(&pkt), sizeof(ColonetRobotServerPacket), 0);
99
  } else {
100
    printf("sending to specific robot.\n");
101
    wl_send_robot_to_robot_global_packet(COLONET_PACKET_GROUP_ID,
102
                                         (char)msg_type, (char*)(&pkt),
103
                                         sizeof(ColonetRobotServerPacket),
104
                                         dest,
105
                                         COLONET_RESPONSE_PACKET_FRAME_ID);
106
  }
107
}
108

    
109
/**************************** Private functions ******************************/
110

    
111
static void timeout_handler() {
112
  printf("timeout!\n");
113
}
114

    
115
static void handle_response(int frame, int received) {
116
  printf("handle response\n");
117
}
118

    
119
static void handle_receive(char type, int source, unsigned char* packet,
120
                           int len) {
121
  ColonetRobotServerPacket pkt;
122
  pkt.client_id = packet[0] | (packet[1]<<8) | (packet[2]<<16) |
123
    (packet[3]<<24); //little endian
124

    
125
  memcpy(pkt.data, packet + 5, PACKET_DATA_LEN);
126

    
127
  if (logging_enabled) {
128
    log_packet(packet, len);
129
  }
130

    
131
  message_handler(type, source, pkt.client_id, packet, len);
132

    
133
  printf("handle receive\n");
134
}
135

    
136
static void unregister(void) {
137
  printf("unregister\n");
138
}
139

    
140
/** @brief Analogous to the "SIGNAL" or "ISR" function on the robots.
141
 * Listens for bytes on the wireless port and constructs packets based on them.
142
 * Not part of the ColonetWireless class since a function pointer must be
143
 * passed in starting the thread that runs it (tricky or impossible if it's
144
 * a class function).
145
 *
146
 * @param args Pointer to arguments.  Can be safely casted to ListenerArgs type
147
 * @return NULL
148
 */
149
static void* listen(void* args) {
150
  printf("Called listen.\n");
151
  wl_init();
152
  printf("wl_init succeeded.\n");
153
  PacketGroupHandler pgh = {COLONET_PACKET_GROUP_ID,
154
                            timeout_handler,
155
                            handle_response,
156
                            handle_receive,
157
                            unregister};
158
  wl_register_packet_group(&pgh);
159

    
160
  while (1) {
161
    wl_do();
162
  }
163

    
164
  wl_terminate();
165
  pthread_exit(NULL);
166
  return NULL;
167
}
168

    
169
/** @brief
170
 *
171
 * @param pkt Packet to be logged
172
 *
173
 * @return 0 on success, -1 on failure
174
 */
175
int log_packet(unsigned char* packet, int len)
176
{
177
  FILE* logfile = fopen(log_filename, "a");
178

    
179
  if (logfile == NULL) {
180
    dbg_printf("%s: Error - fopen %s failed.\n", log_filename, __FUNCTION__);
181
    return -1;
182
  }
183

    
184
  for (int i = 0; i < len; i++) {
185
    fprintf(logfile, "%d ", *((unsigned char*)packet + i));
186
  }
187
  fprintf(logfile, "\n");
188

    
189
  fclose(logfile);
190
  return 0;
191
}