Statistics
| Branch: | Revision:

root / code / server / receive.c @ eba71c8c

History | View | Annotate | Download (6.21 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

    
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

    
40
int main(int argc, char *argv[]) {
41
        if (argc != 3) {
42
        fprintf(stderr, "USAGE: %s <server_ip> <port>\n", argv[0]);
43
        exit(1);
44
    }
45
    
46
    // resolve server hostname
47
    server_hostname = argv[1];
48
    struct hostent *my_host = gethostbyname(server_hostname);
49
    if (my_host == NULL) {
50
        printf("Failed to resolve hostname\n");
51
    }
52
    memcpy(&server_addr, my_host->h_addr_list[0], sizeof(struct in_addr));
53
    ip_addr = inet_ntoa(server_addr);
54
    printf("%s -> %s\n", server_hostname, ip_addr);
55

    
56
    // port on server
57
    port = atoi(argv[2]);
58

    
59
    xbee_lib_init();
60
    while(1) {
61
            listen_to_xbee();
62
    }
63
        return 0;
64
}
65

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

    
94
        if (tcsetattr(xbee_stream, TCSANOW, &options)) {
95
                printf("Error setting attributes.\n");
96
                return -1;
97
        }
98

    
99
        return 0;
100
}
101

    
102
/**
103
 * Thread that listens to the xbee.
104
 **/
105
static void* listen_to_xbee() {
106
        char c;
107
        printf("Listening...\n");
108
        fflush(stdout);
109

    
110
    wl_relay_update();
111
        
112
    usleep(1000);
113

    
114
        return NULL;
115
}
116

    
117
static int xbee_read(char* buf, int size) {
118
        if (read(xbee_stream, buf, size) == -1) {
119
                printf("Failed to read from xbee.\r\n");
120
                return -1;
121
        }
122

    
123
        return 0;
124
}
125

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

    
145
    char     rec;
146
    uint16_t len;
147
    uint16_t src;
148
    uint8_t  rssi;
149
    uint8_t  m_state;
150
    uint16_t time_left;
151
    uint8_t  btn_status, sonar_status;
152
    uint8_t  checksum;
153

    
154
    int timeout_count = 0;
155

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

    
172
    xbee_read(&rec, 1);
173
    len = (uint8_t)rec << 8;
174
    xbee_read(&rec, 1);
175
    len |= (uint8_t)rec;
176

    
177
    char send_buf[len+4];
178
    send_buf[0] = 0x7E;
179
    send_buf[1] = ((uint8_t)len >> 8);
180
    send_buf[2] = (uint8_t)len;
181
    
182
    int i;
183
    for (i = 0; i <= len; i++) {
184
        xbee_read(&rec, 1);
185
        send_buf[i+3] = rec;
186
    }
187

    
188
    src = (send_buf[4] << 8) | send_buf[5];
189
    m_state = send_buf[9];
190
    time_left = ((uint8_t)send_buf[10] << 8) | (uint8_t)send_buf[11];
191
    printf("len MSB: %x", (uint8_t)send_buf[10]);
192
    printf(" len LSB: %x ", (uint8_t)send_buf[11]);
193

    
194
    btn_status = send_buf[12];
195
    sonar_status = send_buf[13];
196

    
197
    // sanity check - discard packet if it fails
198
    if ( (btn_status != 0 && btn_status != 1) ||
199
         (sonar_status != 0 && sonar_status != 1) ) {
200
        printf("bad packet from meter, not sent to server\n");
201
        return;
202
    }
203

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

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

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

    
246
    printf("Socket created!?\n");
247

    
248
    return sock;
249
}
250