-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathWifi.cpp
137 lines (112 loc) · 3.07 KB
/
Wifi.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "Wifi.h"
using namespace myRIO;
/**
* Create a Wifi handler.
* This detach a thread so it can read and write synchronously without blocking other tasks.
* @param func function to call when receiving data
*/
Wifi::Wifi(std::function<void(long setpoint)> func) : connected(false), _socket(0), _func(func) {
_socketThread = std::thread([&]() {
openServer();
}
);
_socketThread.detach();
}
/**
* Create a wifi server.
* Ressources used to understand C socket programming :
* https://www.geeksforgeeks.org/socket-programming-cc/
* http://manpages.ubuntu.com/manpages/cosmic/en/man2/accept.2.html
*/
void Wifi::openServer() {
int inBytes;
long val;
char buffer[2];
// opening a server : AF_INET (IPv4), SOCK_STREAM (TCP)
int err, opt = 1;
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if(server_fd==0) { perror("socket"); return; }
err = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_KEEPALIVE, &opt, sizeof(opt));
if(err) { perror("setsockopt"); return; }
// defining server address and port
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(50000);
// binding the server address
err = bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(err<0) { perror("bind"); return; }
// listening for incoming connections : blocking
err = listen(server_fd, 10);
if(err<0) { perror("listen"); return; }
do {
val = 0;
struct sockaddr client_addr = {0};
socklen_t client_addr_size = sizeof(client_addr);
std::cout << "Wifi - Waiting for connection" << std::endl;
// wait for a client connection
_socket = accept(server_fd, &client_addr, &client_addr_size);
if(_socket==-1) { perror("accept"); return; }
std::cout << "Wifi - Connected" << std::endl;
connected = true;
while(val != 30000) {
ioctl(_socket, FIONREAD, &inBytes);
if(inBytes>0) {
read(_socket , buffer, 4);
val = buffer[3]<<24 | buffer[2]<<16 | buffer[1]<<8 | buffer[0];
if(val != 30000)
_func(val);
}
//Time::wait_ms(5);
}
err = close(_socket);
if(err<0) { perror("close"); return; }
std::cout << "Wifi - Socket closed";
connected = false;
} while(true);
}
/**
* Send data to the client
* @param angle the angle to send
*/
void Wifi::updateAngle(short angle) {
if(connected)
writeShort(angle);
}
/**
* Returns the state of the socket
* @return true if wifi is connected
*/
bool Wifi::isConnected() {
return connected;
}
/**
* Write a char to the socket
* @param c a char to write
*/
void Wifi::writeChar(char c) {
write(_socket, reinterpret_cast<const char*>(&c), sizeof(char));
}
/**
* Write a short to the socket
* @param s a short to write
*/
void Wifi::writeShort(short s) {
write(_socket, reinterpret_cast<const char*>(&s), sizeof(short));
}
/**
* Write a long to the socket
* @param l a long to write
*/
void Wifi::writeLong(long l) {
write(_socket, reinterpret_cast<const char*>(&l), sizeof(long));
}
/**
* Close the socket if we are still connected
*/
Wifi::~Wifi() {
if(connected) {
writeShort(30000);
close(_socket);
}
}