Statistics
| Branch: | Revision:

root / code / server / receive.c @ 262b766b

History | View | Annotate | Download (6.4 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
char *server_hostname;
30
char *ip_addr;
31
struct in_addr server_addr;
32
int  port;
33
int  socket_open();
34

    
35
static int xbee_read(char* buf, int size);
36
static void* listen_to_xbee();
37
int xbee_lib_init();
38
void wl_relay_update();
39
void sigint_handler(int param);
40

    
41

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

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

    
61
    // port on server
62
    port = atoi(argv[2]);
63

    
64
    xbee_lib_init();
65
    while(1) {
66
            listen_to_xbee();
67
    }
68
        return 0;
69
}
70

    
71
int xbee_lib_init() {
72
        xbee_stream = open(xbee_com_port, O_RDWR);
73
        if (xbee_stream == -1) {
74
                printf("Failed to open connection to XBee on port ");
75
                printf("%i\n", *xbee_com_port);
76
                return -1;
77
        }
78
    else {
79
                  printf("Successfully opened connection to XBee on port ");
80
                printf("%i\n", (int)(*xbee_com_port));
81
        }
82
        // set baud rate, etc. correctly
83
        struct termios options;
84
        if(tcgetattr(xbee_stream, &options))
85
                printf("Error getting attributes");
86
        cfsetispeed(&options, B9600);
87
        cfsetospeed(&options, B9600);
88
        options.c_iflag &= ~ICRNL;
89
        options.c_oflag &= ~OCRNL;
90
        options.c_cflag |= (CLOCAL | CREAD);
91
        options.c_cflag &= ~PARENB;
92
        options.c_cflag &= ~CSTOPB;
93
        options.c_cflag &= ~CSIZE;
94
        options.c_cflag |= CS8;
95
        options.c_lflag &= ~ICANON;
96
        options.c_cc[VMIN] = 1;
97
        options.c_cc[VTIME] = 50;
98

    
99
        if (tcsetattr(xbee_stream, TCSANOW, &options)) {
100
                printf("Error setting attributes.\n");
101
                return -1;
102
        }
103

    
104
        return 0;
105
}
106

    
107
/**
108
 * Thread that listens to the xbee.
109
 **/
110
static void* listen_to_xbee() {
111
        char c;
112
        printf("Listening...\n");
113
        fflush(stdout);
114

    
115
    wl_relay_update();
116
        
117
    usleep(1000);
118

    
119
        return NULL;
120
}
121

    
122
static int xbee_read(char* buf, int size) {
123
        if (read(xbee_stream, buf, size) == -1) {
124
                printf("Failed to read from xbee.\r\n");
125
                return -1;
126
        }
127

    
128
        return 0;
129
}
130

    
131
void wl_relay_update() {
132
    // XBee API Mode Packet:
133
    // byte 0 = start delimiter (0x7E)
134
    // byte 1 = MSB of packet length (length of frame data)
135
    // byte 2 = LSB of packet length
136
    // byte 3 = API Identifier (0x81)
137
    // byte 4 = MSB of destination address
138
    // byte 5 = LSB of destination address
139
    // byte 6 = RSSI
140
    // byte 7 = Options (0x00)
141
    // byte 8 = Packet Type
142
    // byte 9 to n = RF Data (char*)
143
    //      9 = m_state
144
    //     10 = MSB of time_left
145
    //     11 = LSB of time_left
146
    //     12 = Button Status
147
    //     13 = Sonar Status
148
    // byte n+1 = checksum (add bytes 3 to n, subtract LSB from 0xFF)
149

    
150
    char     rec;
151
    uint16_t len;
152
    uint16_t src;
153
    uint8_t  rssi;
154
    uint8_t  m_state;
155
    uint16_t time_left;
156
    uint8_t  btn_status, sonar_status;
157
    uint8_t  checksum;
158

    
159
    int timeout_count = 0;
160

    
161
    // loop until we receive valid start byte
162
    xbee_read(&rec, 1);
163
    while (rec != 0x7E) {
164
        printf("Incorrect Start Delimiter\n");
165
        xbee_read(&rec, 1);
166
        timeout_count++;
167
        // try to reconnect to serial port:
168
        //  for when xbee is unplugged
169
        if (timeout_count > 500) {
170
            printf("are we unplugged?\n");
171
            timeout_count = 0;
172
            close(xbee_stream);
173
            xbee_lib_init();
174
        } 
175
    }
176

    
177
    xbee_read(&rec, 1);
178
    len = (uint8_t)rec << 8;
179
    xbee_read(&rec, 1);
180
    len |= (uint8_t)rec;
181

    
182
    char send_buf[len+4];
183
    send_buf[0] = 0x7E;
184
    send_buf[1] = ((uint8_t)len >> 8);
185
    send_buf[2] = (uint8_t)len;
186
    
187
    int i;
188
    for (i = 0; i <= len; i++) {
189
        xbee_read(&rec, 1);
190
        send_buf[i+3] = rec;
191
    }
192

    
193
    src = (send_buf[4] << 8) | send_buf[5];
194
    m_state = send_buf[9];
195
    time_left = ((uint8_t)send_buf[10] << 8) | (uint8_t)send_buf[11];
196
    //printf("len MSB: %x", (uint8_t)send_buf[10]);
197
    //printf(" len LSB: %x ", (uint8_t)send_buf[11]);
198

    
199
    btn_status = send_buf[12];
200
    sonar_status = send_buf[13];
201

    
202
    // sanity check - discard packet if it fails
203
    if ( (btn_status != 0 && btn_status != 1) ||
204
         (sonar_status != 0 && sonar_status != 1) ) {
205
        printf("bad packet from meter, not sent to server\n");
206
        return;
207
    }
208

    
209
    #ifdef USE_SERVER
210
    int sock = socket_open();
211
    printf("sending to server\n");
212
    if (send(sock, send_buf, len+4, 0) != len+4) {
213
            printf("Mismatch in number of sent bytes");
214
            close(sock);
215
            return;
216
    }
217
    close(sock);
218
    #endif
219

    
220
    printf("Meter %X is now ", src);
221
    if (m_state == SPOT_FREE) {
222
        printf("unoccupied. ");
223
    }
224
    else {
225
        printf ("occupied. ");
226
    }
227
    printf("There are %d seconds left. Button Status=%d. Sonar Status=%d\n",
228
           time_left, btn_status, sonar_status);
229
}
230

    
231
int socket_open() {
232
    int sock;
233
    struct sockaddr_in my_server;
234
    
235
    // Create the TCP socket
236
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
237
            printf("Failed to create socket\n");
238
            return -1;
239
    }
240
    // Construct the server sockaddr_in structure
241
    memset(&my_server, 0, sizeof(my_server));        // Clear struct
242
    my_server.sin_family = AF_INET;                  // Internet/IP
243
    my_server.sin_addr.s_addr = inet_addr(ip_addr);  // IP address
244
    my_server.sin_port = htons(port);                // server port
245
    // Establish connection
246
    if (connect(sock, (struct sockaddr *) &my_server, sizeof(my_server)) < 0) {
247
            printf("Failed to connect with server\n");
248
            return -1;
249
    }
250

    
251
    //printf("Socket created!?\n");
252

    
253
    return sock;
254
}
255

    
256
void sigint_handler(int param) {
257
    printf("Relay node shutting down.\n");
258
    exit(0);
259
}
260