root / code / server / receive.c @ 82a24877
History | View | Annotate | Download (6.19 KB)
| 1 |
#include <termios.h> |
|---|---|
| 2 |
#include <fcntl.h> |
| 3 |
#include <stdio.h> |
| 4 |
#include <stdlib.h> |
| 5 |
#include <string.h> |
| 6 |
#include <unistd.h> |
| 7 |
#include <stdint.h> |
| 8 |
#include <arpa/inet.h> |
| 9 |
#include <netinet/in.h> |
| 10 |
#include <netdb.h> |
| 11 |
|
| 12 |
#define USE_SERVER
|
| 13 |
|
| 14 |
#define XBEE_PORT_DEFAULT "/dev/ttyUSB0" //or try USB1 |
| 15 |
#define XBEE_GET_PACKET_TIMEOUT 1000 |
| 16 |
#define XBEE_BUFFER_SIZE 128 |
| 17 |
|
| 18 |
#define SPOT_FREE 0 |
| 19 |
#define SPOT_TAKEN 1 |
| 20 |
|
| 21 |
static char* xbee_com_port = XBEE_PORT_DEFAULT; |
| 22 |
static int xbee_stream; |
| 23 |
char arrival_buf[XBEE_BUFFER_SIZE];
|
| 24 |
// location of last unread byte in buffer
|
| 25 |
volatile int buffer_last = 0; |
| 26 |
// first unread byte in buffer
|
| 27 |
volatile int buffer_first = 0; |
| 28 |
char *server_hostname;
|
| 29 |
char *ip_addr;
|
| 30 |
struct in_addr server_addr;
|
| 31 |
int port;
|
| 32 |
int socket_open();
|
| 33 |
|
| 34 |
static int xbee_read(char* buf, int size); |
| 35 |
static void* listen_to_xbee(); |
| 36 |
int xbee_lib_init();
|
| 37 |
void wl_relay_update();
|
| 38 |
|
| 39 |
int main(int argc, char *argv[]) { |
| 40 |
if (argc != 3) { |
| 41 |
fprintf(stderr, "USAGE: %s <server_ip> <port>\n", argv[0]); |
| 42 |
exit(1);
|
| 43 |
} |
| 44 |
|
| 45 |
// resolve server hostname
|
| 46 |
server_hostname = argv[1];
|
| 47 |
struct hostent *my_host = gethostbyname(server_hostname);
|
| 48 |
if (my_host == NULL) { |
| 49 |
printf("Failed to resolve hostname\n");
|
| 50 |
} |
| 51 |
memcpy(&server_addr, my_host->h_addr_list[0], sizeof(struct in_addr)); |
| 52 |
ip_addr = inet_ntoa(server_addr); |
| 53 |
printf("%s -> %s\n", server_hostname, ip_addr);
|
| 54 |
|
| 55 |
// port on server
|
| 56 |
port = atoi(argv[2]);
|
| 57 |
|
| 58 |
xbee_lib_init(); |
| 59 |
while(1) { |
| 60 |
listen_to_xbee(); |
| 61 |
} |
| 62 |
return 0; |
| 63 |
} |
| 64 |
|
| 65 |
int xbee_lib_init() {
|
| 66 |
xbee_stream = open(xbee_com_port, O_RDWR); |
| 67 |
if (xbee_stream == -1) { |
| 68 |
printf("Failed to open connection to XBee on port ");
|
| 69 |
printf("%i\n", *xbee_com_port);
|
| 70 |
return -1; |
| 71 |
} |
| 72 |
else {
|
| 73 |
printf("Successfully opened connection to XBee on port ");
|
| 74 |
printf("%i\n", (int)(*xbee_com_port)); |
| 75 |
} |
| 76 |
// set baud rate, etc. correctly
|
| 77 |
struct termios options;
|
| 78 |
if(tcgetattr(xbee_stream, &options))
|
| 79 |
printf("Error getting attributes");
|
| 80 |
cfsetispeed(&options, B9600); |
| 81 |
cfsetospeed(&options, B9600); |
| 82 |
options.c_iflag &= ~ICRNL; |
| 83 |
options.c_oflag &= ~OCRNL; |
| 84 |
options.c_cflag |= (CLOCAL | CREAD); |
| 85 |
options.c_cflag &= ~PARENB; |
| 86 |
options.c_cflag &= ~CSTOPB; |
| 87 |
options.c_cflag &= ~CSIZE; |
| 88 |
options.c_cflag |= CS8; |
| 89 |
options.c_lflag &= ~ICANON; |
| 90 |
options.c_cc[VMIN] = 1;
|
| 91 |
options.c_cc[VTIME] = 50;
|
| 92 |
|
| 93 |
if (tcsetattr(xbee_stream, TCSANOW, &options)) {
|
| 94 |
printf("Error setting attributes.\n");
|
| 95 |
return -1; |
| 96 |
} |
| 97 |
|
| 98 |
return 0; |
| 99 |
} |
| 100 |
|
| 101 |
/**
|
| 102 |
* Thread that listens to the xbee.
|
| 103 |
**/
|
| 104 |
static void* listen_to_xbee() { |
| 105 |
char c;
|
| 106 |
printf("Listening...\n");
|
| 107 |
fflush(stdout); |
| 108 |
|
| 109 |
wl_relay_update(); |
| 110 |
|
| 111 |
usleep(1000);
|
| 112 |
|
| 113 |
return NULL; |
| 114 |
} |
| 115 |
|
| 116 |
static int xbee_read(char* buf, int size) { |
| 117 |
if (read(xbee_stream, buf, size) == -1) { |
| 118 |
printf("Failed to read from xbee.\r\n");
|
| 119 |
return -1; |
| 120 |
} |
| 121 |
|
| 122 |
return 0; |
| 123 |
} |
| 124 |
|
| 125 |
void wl_relay_update() {
|
| 126 |
// XBee API Mode Packet:
|
| 127 |
// byte 0 = start delimiter (0x7E)
|
| 128 |
// byte 1 = MSB of packet length (length of frame data)
|
| 129 |
// byte 2 = LSB of packet length
|
| 130 |
// byte 3 = API Identifier (0x81)
|
| 131 |
// byte 4 = MSB of destination address
|
| 132 |
// byte 5 = LSB of destination address
|
| 133 |
// byte 6 = RSSI
|
| 134 |
// byte 7 = Options (0x00)
|
| 135 |
// byte 8 = Packet Type
|
| 136 |
// byte 9 to n = RF Data (char*)
|
| 137 |
// 9 = m_state
|
| 138 |
// 10 = MSB of time_left
|
| 139 |
// 11 = LSB of time_left
|
| 140 |
// 12 = Button Status
|
| 141 |
// 13 = Sonar Status
|
| 142 |
// byte n+1 = checksum (add bytes 3 to n, subtract LSB from 0xFF)
|
| 143 |
|
| 144 |
char rec;
|
| 145 |
uint16_t len; |
| 146 |
uint16_t src; |
| 147 |
uint8_t rssi; |
| 148 |
uint8_t m_state; |
| 149 |
uint16_t time_left; |
| 150 |
uint8_t btn_status, sonar_status; |
| 151 |
uint8_t checksum; |
| 152 |
|
| 153 |
int timeout_count = 0; |
| 154 |
|
| 155 |
// loop until we receive valid start byte
|
| 156 |
xbee_read(&rec, 1);
|
| 157 |
while (rec != 0x7E) { |
| 158 |
printf("Incorrect Start Delimiter\n");
|
| 159 |
xbee_read(&rec, 1);
|
| 160 |
timeout_count++; |
| 161 |
// try to reconnect to serial port:
|
| 162 |
// for when xbee is unplugged
|
| 163 |
if (timeout_count > 500) { |
| 164 |
printf("are we unplugged?\n");
|
| 165 |
timeout_count = 0;
|
| 166 |
close(xbee_stream); |
| 167 |
xbee_lib_init(); |
| 168 |
} |
| 169 |
} |
| 170 |
|
| 171 |
xbee_read(&rec, 1);
|
| 172 |
len = (uint8_t)rec << 8;
|
| 173 |
xbee_read(&rec, 1);
|
| 174 |
len |= (uint8_t)rec; |
| 175 |
|
| 176 |
char send_buf[len+4]; |
| 177 |
send_buf[0] = 0x7E; |
| 178 |
send_buf[1] = ((uint8_t)len >> 8); |
| 179 |
send_buf[2] = (uint8_t)len;
|
| 180 |
|
| 181 |
int i;
|
| 182 |
for (i = 0; i <= len; i++) { |
| 183 |
xbee_read(&rec, 1);
|
| 184 |
send_buf[i+3] = rec;
|
| 185 |
} |
| 186 |
|
| 187 |
src = (send_buf[4] << 8) | send_buf[5]; |
| 188 |
m_state = send_buf[9];
|
| 189 |
time_left = ((uint8_t)send_buf[10] << 8) | (uint8_t)send_buf[11]; |
| 190 |
//printf("len MSB: %x", (uint8_t)send_buf[10]);
|
| 191 |
//printf(" len LSB: %x ", (uint8_t)send_buf[11]);
|
| 192 |
|
| 193 |
btn_status = send_buf[12];
|
| 194 |
sonar_status = send_buf[13];
|
| 195 |
|
| 196 |
// sanity check - discard packet if it fails
|
| 197 |
if ( (btn_status != 0 && btn_status != 1) || |
| 198 |
(sonar_status != 0 && sonar_status != 1) ) { |
| 199 |
printf("bad packet from meter, not sent to server\n");
|
| 200 |
return;
|
| 201 |
} |
| 202 |
|
| 203 |
#ifdef USE_SERVER
|
| 204 |
int sock = socket_open();
|
| 205 |
//printf("sending to server\n");
|
| 206 |
if (send(sock, send_buf, len+4, 0) != len+4) { |
| 207 |
printf("Mismatch in number of sent bytes");
|
| 208 |
return;
|
| 209 |
} |
| 210 |
close(sock); |
| 211 |
#endif
|
| 212 |
|
| 213 |
printf("Meter %X is now ", src);
|
| 214 |
if (m_state == SPOT_FREE) {
|
| 215 |
printf("unoccupied. ");
|
| 216 |
} |
| 217 |
else {
|
| 218 |
printf ("occupied. ");
|
| 219 |
} |
| 220 |
printf("There are %d seconds left. Button Status=%d. Sonar Status=%d\n",
|
| 221 |
time_left, btn_status, sonar_status); |
| 222 |
} |
| 223 |
|
| 224 |
int socket_open() {
|
| 225 |
int sock;
|
| 226 |
struct sockaddr_in my_server;
|
| 227 |
|
| 228 |
// Create the TCP socket
|
| 229 |
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { |
| 230 |
printf("Failed to create socket\n");
|
| 231 |
return -1; |
| 232 |
} |
| 233 |
// Construct the server sockaddr_in structure
|
| 234 |
memset(&my_server, 0, sizeof(my_server)); // Clear struct |
| 235 |
my_server.sin_family = AF_INET; // Internet/IP
|
| 236 |
my_server.sin_addr.s_addr = inet_addr(ip_addr); // IP address
|
| 237 |
my_server.sin_port = htons(port); // server port
|
| 238 |
// Establish connection
|
| 239 |
if (connect(sock, (struct sockaddr *) &my_server, sizeof(my_server)) < 0) { |
| 240 |
printf("Failed to connect with server\n");
|
| 241 |
return -1; |
| 242 |
} |
| 243 |
|
| 244 |
//printf("Socket created!?\n");
|
| 245 |
|
| 246 |
return sock;
|
| 247 |
} |
| 248 |
|