Statistics
| Branch: | Revision:

root / code / server / receive.c @ 852969ee

History | View | Annotate | Download (6.86 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
#include <signal.h>
12

    
13
//#define USE_SERVER
14

    
15
#define XBEE_PORT_DEFAULT "/dev/ttyUSB0" //or try USB1
16
#define XBEE_GET_PACKET_TIMEOUT 1000
17
#define XBEE_BUFFER_SIZE        128
18

    
19
#define SPOT_FREE  0
20
#define SPOT_TAKEN 1
21

    
22
static char* xbee_com_port = XBEE_PORT_DEFAULT;
23
static int xbee_stream;
24
char arrival_buf[XBEE_BUFFER_SIZE];
25
// location of last unread byte in buffer
26
volatile int buffer_last = 0;
27
// first unread byte in buffer
28
volatile int buffer_first = 0;
29
int server_sock;
30
int server_errors;
31

    
32
char *server_hostname;
33
char *ip_addr;
34
struct in_addr server_addr;
35
int  port;
36
int  socket_open();
37

    
38
static int xbee_read(char* buf, int size);
39
static void* listen_to_xbee();
40
int xbee_lib_init();
41
void wl_relay_update();
42
void sigint_handler(int param);
43

    
44

    
45
int main(int argc, char *argv[]) {
46
   
47
        if (argc != 3) {
48
        fprintf(stderr, "USAGE: %s <server_ip> <port>\n", argv[0]);
49
        exit(1);
50
    }
51
    
52
    server_sock = 0;
53
    server_errors = 0;
54
    signal(SIGINT, sigint_handler);
55

    
56
    // resolve server hostname
57
    server_hostname = argv[1];
58
    struct hostent *my_host = gethostbyname(server_hostname);
59
    if (my_host == NULL) {
60
        printf("Failed to resolve hostname\n");
61
    }
62
    memcpy(&server_addr, my_host->h_addr_list[0], sizeof(struct in_addr));
63
    ip_addr = inet_ntoa(server_addr);
64
    printf("%s -> %s\n", server_hostname, ip_addr);
65

    
66
    // port on server
67
    port = atoi(argv[2]);
68
    
69
    // open connection to server
70
    #ifdef USE_SERVER
71
    server_sock = socket_open();
72
    #endif
73

    
74
    xbee_lib_init();
75
    while(1) {
76
            listen_to_xbee();
77

    
78
        #ifdef USE_SERVER
79
        if (server_errors > SERVER_ERROR_THRESH) {
80
            close(server_socket);
81
            server_socket = socket_open();
82
            server_errors = 0;
83
        }
84
        #endif
85
    }
86
        return 0;
87
}
88

    
89
int xbee_lib_init() {
90
        xbee_stream = open(xbee_com_port, O_RDWR);
91
        if (xbee_stream == -1) {
92
                printf("Failed to open connection to XBee on port ");
93
                printf("%i\n", *xbee_com_port);
94
                return -1;
95
        }
96
    else {
97
                  printf("Successfully opened connection to XBee on port ");
98
                printf("%i\n", (int)(*xbee_com_port));
99
        }
100
        // set baud rate, etc. correctly
101
        struct termios options;
102
        if(tcgetattr(xbee_stream, &options))
103
                printf("Error getting attributes");
104
        cfsetispeed(&options, B9600);
105
        cfsetospeed(&options, B9600);
106
        options.c_iflag &= ~ICRNL;
107
        options.c_oflag &= ~OCRNL;
108
        options.c_cflag |= (CLOCAL | CREAD);
109
        options.c_cflag &= ~PARENB;
110
        options.c_cflag &= ~CSTOPB;
111
        options.c_cflag &= ~CSIZE;
112
        options.c_cflag |= CS8;
113
        options.c_lflag &= ~ICANON;
114
        options.c_cc[VMIN] = 1;
115
        options.c_cc[VTIME] = 50;
116

    
117
        if (tcsetattr(xbee_stream, TCSANOW, &options)) {
118
                printf("Error setting attributes.\n");
119
                return -1;
120
        }
121

    
122
        return 0;
123
}
124

    
125
/**
126
 * Thread that listens to the xbee.
127
 **/
128
static void* listen_to_xbee() {
129
        char c;
130
        printf("Listening...\n");
131
        fflush(stdout);
132

    
133
    wl_relay_update();
134
        
135
    usleep(1000);
136

    
137
        return NULL;
138
}
139

    
140
static int xbee_read(char* buf, int size) {
141
        if (read(xbee_stream, buf, size) == -1) {
142
                printf("Failed to read from xbee.\r\n");
143
                return -1;
144
        }
145

    
146
        return 0;
147
}
148

    
149
void wl_relay_update() {
150
    // XBee API Mode Packet:
151
    // byte 0 = start delimiter (0x7E)
152
    // byte 1 = MSB of packet length (length of frame data)
153
    // byte 2 = LSB of packet length
154
    // byte 3 = API Identifier (0x81)
155
    // byte 4 = MSB of destination address
156
    // byte 5 = LSB of destination address
157
    // byte 6 = RSSI
158
    // byte 7 = Options (0x00)
159
    // byte 8 = Packet Type
160
    // byte 9 to n = RF Data (char*)
161
    //      9 = m_state
162
    //     10 = MSB of time_left
163
    //     11 = LSB of time_left
164
    //     12 = Button Status
165
    //     13 = Sonar Status
166
    // byte n+1 = checksum (add bytes 3 to n, subtract LSB from 0xFF)
167

    
168
    char     rec;
169
    uint16_t len;
170
    uint16_t src;
171
    uint8_t  rssi;
172
    uint8_t  m_state;
173
    uint16_t time_left;
174
    uint8_t  btn_status, sonar_status;
175
    uint8_t  checksum;
176

    
177
    int timeout_count = 0;
178

    
179
    // loop until we receive valid start byte
180
    xbee_read(&rec, 1);
181
    while (rec != 0x7E) {
182
        printf("Incorrect Start Delimiter\n");
183
        xbee_read(&rec, 1);
184
        timeout_count++;
185
        // try to reconnect to serial port:
186
        //  for when xbee is unplugged
187
        if (timeout_count > 500) {
188
            printf("are we unplugged?\n");
189
            timeout_count = 0;
190
            close(xbee_stream);
191
            xbee_lib_init();
192
        } 
193
    }
194

    
195
    xbee_read(&rec, 1);
196
    len = (uint8_t)rec << 8;
197
    xbee_read(&rec, 1);
198
    len |= (uint8_t)rec;
199

    
200
    char send_buf[len+4];
201
    send_buf[0] = 0x7E;
202
    send_buf[1] = ((uint8_t)len >> 8);
203
    send_buf[2] = (uint8_t)len;
204
    
205
    int i;
206
    for (i = 0; i <= len; i++) {
207
        xbee_read(&rec, 1);
208
        send_buf[i+3] = rec;
209
    }
210

    
211
    src = (send_buf[4] << 8) | send_buf[5];
212
    m_state = send_buf[9];
213
    time_left = ((uint8_t)send_buf[10] << 8) | (uint8_t)send_buf[11];
214
    //printf("len MSB: %x", (uint8_t)send_buf[10]);
215
    //printf(" len LSB: %x ", (uint8_t)send_buf[11]);
216

    
217
    btn_status = send_buf[12];
218
    sonar_status = send_buf[13];
219

    
220
    // sanity check - discard packet if it fails
221
    if ( (btn_status != 0 && btn_status != 1) ||
222
         (sonar_status != 0 && sonar_status != 1) ) {
223
        printf("bad packet from meter, not sent to server\n");
224
        return;
225
    }
226

    
227
    #ifdef USE_SERVER
228
    //int sock = socket_open();
229
    //printf("sending to server\n");
230
    if (send(server_sock, send_buf, len+4, 0) != len+4) {
231
            printf("Mismatch in number of sent bytes");
232
            server_errors++;
233
            //close(server_sock);
234
            return;
235
    }
236
    //close(sock);
237
    #endif
238

    
239
    printf("Meter %X is now ", src);
240
    if (m_state == SPOT_FREE) {
241
        printf("unoccupied. ");
242
    }
243
    else {
244
        printf ("occupied. ");
245
    }
246
    printf("There are %d seconds left. Button Status=%d. Sonar Status=%d\n",
247
           time_left, btn_status, sonar_status);
248
}
249

    
250
int socket_open() {
251
    int sock;
252
    struct sockaddr_in my_server;
253
    
254
    // Create the TCP socket
255
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
256
            printf("Failed to create socket\n");
257
            return -1;
258
    }
259
    // Construct the server sockaddr_in structure
260
    memset(&my_server, 0, sizeof(my_server));        // Clear struct
261
    my_server.sin_family = AF_INET;                  // Internet/IP
262
    my_server.sin_addr.s_addr = inet_addr(ip_addr);  // IP address
263
    my_server.sin_port = htons(port);                // server port
264
    // Establish connection
265
    if (connect(sock, (struct sockaddr *) &my_server, sizeof(my_server)) < 0) {
266
            printf("Failed to connect with server\n");
267
            return -1;
268
    }
269

    
270
    //printf("Socket created!?\n");
271

    
272
    return sock;
273
}
274

    
275
void sigint_handler(int param) {
276
    close(server_sock);
277
    printf("Relay node shutting down.\n");
278
    exit(0);
279
}
280