9 #define WIN32_LEAN_AND_MEAN
13 #define bailout(msg) ({\
15 int error = WSAGetLastError(); \
16 if (FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\
17 NULL, error, 0, (char*)&buf, 0, NULL) && error) \
18 fprintf(stderr, "%s. Error message: %s\n", (msg), buf);\
20 fprintf(stderr, "%s. Error code: %d\n", (msg), error); \
23 #define SHUT_RDWR SD_BOTH
25 static inline const char * inet_ntop(
int af,
const void * restrict src,
char * restrict dst, socklen_t size);
26 static inline int inet_pton(
int af,
const char *src,
void *dst);
28 typedef int socklen_t;
30 #define socksetblock(sock, y_n) \
31 ioctlsocket((sock), FIONBIO, &(unsigned long){!(y_n)})
36 #define INVALID_SOCKET (-1)
37 #define SOCKET_ERROR (-1)
38 #define bailout(msg) perror((msg))
39 #define closesocket close
40 #define socksetblock(sock, y_n) ((y_n) ? \
41 fcntl((sock), F_SETFL, fcntl((sock), F_GETFL, 0) & ~O_NONBLOCK) : \
42 fcntl((sock), F_SETFL, O_NONBLOCK))
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
67 #define UDP_RECV_TIMEOUT 6
68 #define TCP_CONNECT_TIMEOUT 1
89 if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
91 fprintf(stderr,
"Failed to initialize Winsock2. Error Code : %d\n", WSAGetLastError());
101 struct sockaddr_in servaddr;
102 memset(&servaddr, 0,
sizeof servaddr);
105 if (serial && strchr(serial,
'.'))
112 servaddr.sin_family = AF_INET;
113 switch(inet_pton(AF_INET, serial, &servaddr.sin_addr)){
115 case 0: fprintf(stderr,
"Invalid IP specified '%s'\n", serial);
return NULL;
116 case -1:
bailout(
"Parsing IP failed");
return NULL;
118 strncpy(fdp->
name,
"[n/a]",
sizeof fdp->
name);
122 strncpy(fdp->
ip, serial,
sizeof fdp->
ip);
127 bailout(
"Failed to create socket");
131 servaddr.sin_family = AF_INET;
132 servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
133 servaddr.sin_port = htons(
UDP_PORT);
134 if (bind(fd, (
struct sockaddr *)&servaddr,
sizeof servaddr) ==
SOCKET_ERROR)
141 struct sockaddr_in cliaddr;
142 socklen_t len =
sizeof cliaddr;
144 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (
void*)&tv_udp,
sizeof tv_udp);
145 n = recvfrom(fd, buffer,
sizeof buffer,0,(
struct sockaddr *)&cliaddr,&len);
149 bailout(
"Failed to recieve broadcast");
155 "Serial-Number: %s\r\n"
160 }
while(serial && strcmp(serial, fdp->
serial) != 0);
162 n = sendto(fd, (
char[]){0x00}, 1, 0, (
struct sockaddr *)&cliaddr,
sizeof cliaddr);
166 bailout(
"Failed to initiate handshake");
170 memset(&servaddr, 0,
sizeof servaddr);
173 servaddr.sin_family = AF_INET;
174 servaddr.sin_addr.s_addr = cliaddr.sin_addr.s_addr;
175 inet_ntop(AF_INET, &cliaddr.sin_addr, fdp->
ip,
sizeof fdp->
ip);
176 servaddr.sin_port = htons(fdp->
tcp_port);
179 fd = socket(AF_INET, SOCK_STREAM, 0);
183 n = connect(fd, (
struct sockaddr *)&servaddr,
sizeof servaddr);
188 if (
select(fd + 1, NULL, &fdset, NULL, &tv_tcp) == 1)
192 socklen_t len =
sizeof so_error;
193 getsockopt(fd, SOL_SOCKET, SO_ERROR, &so_error, &len);
203 bailout(
"Failed to initiate TCP connection");
207 n = snprintf(buffer,
sizeof buffer,
208 "GET /target?sn=%s VMTP1.0\nProtocol: %s",
210 n = sendto(fd, buffer, n, 0, (
struct sockaddr *)&servaddr,
sizeof servaddr);
214 bailout(
"Failed to handshake over TCP");
218 n=recvfrom(fd, buffer,
sizeof buffer, 0, NULL, NULL);
222 bailout(
"Failed to recieve TCP-connection confirmation");
229 fdp->sock = (LPVOID)fd;
231 fdp->
fd[0] = fdp->
fd[1] = fd;
243 shutdown(*(
SOCKET*)sock, SHUT_RDWR);
256 const wchar_t *
tcp_error(
void* fd_) { (void)fd_;
return L
"Errors not implemented yet";}
259 int tcp_write(
void* sock,
const u8* buf,
size_t count) {
261 return send(*(
SOCKET*)sock, (
char*)buf, count, 0);
263 int tcp_read(
void* sock,
u8* buf,
size_t count,
int milliseconds) {
267 return recv(*(
SOCKET*)sock, (
char*)buf, count, 0);
277 static inline const char *inet_ntop(
int af,
const void * restrict src,
char * restrict dst, socklen_t size)
280 union {
u32 addr;
u8 sub[4];} ip = {((
struct in_addr*)src)->s_addr};
281 snprintf(dst, size,
"%u.%u.%u.%u",
282 ip.sub[0], ip.sub[1], ip.sub[2], ip.sub[3]);
285 static inline int inet_pton(
int af,
const char *src,
void *dst)
288 union {
u32 addr;
u8 sub[4];} ip;
290 sscanf(src,
"%hhu.%hhu.%hhu.%hhu",
291 &ip.sub[0], &ip.sub[1], &ip.sub[2], &ip.sub[3]);
295 ((
struct in_addr*)dst)->s_addr = ip.addr;
#define UDP_PORT
default UDP broadcast port
#define TCP_CONNECT_TIMEOUT
#define socksetblock(sock, y_n)
int bt_write(void *fd_, const u8 *buf, size_t count)
writes buf[1] till buf[count - 2] to device
int bt_read(void *fd_, u8 *buf, size_t count, int milliseconds)
writes buf[1] till buf[count - 2] to device
Input/Output wrappers for Bluetooth.
void * tcp_open(const char *serial, unsigned timeout)
connects to a ev3 device on the same subnet.
int SOCKET
BSD Sockets/Winsock2 I/O wrappers.
int(* tcp_write)(void *device, const u8 *buf, size_t count)
writes buf[1] till buf[count - 2] to device
void tcp_close(void *sock)
releases the socket file descriptor opened by tcp_open()
BSD sockets/Winsock2 Input/Output wrappers.
const wchar_t * tcp_error(void *fd_)
Returns an error string describing the last error occured.
int(* tcp_read)(void *device, u8 *buf, size_t count, int milliseconds)
writes buf[1] till buf[count - 2] to device