Discovery Bind and Send

This commit is contained in:
Florian Märkl 2019-06-14 09:55:00 +02:00
commit 3ac355608e
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
2 changed files with 98 additions and 11 deletions

View file

@ -19,6 +19,10 @@
#define CHIAKI_DISCOVERY_H #define CHIAKI_DISCOVERY_H
#include "common.h" #include "common.h"
#include "thread.h"
#include <sys/types.h>
#include <sys/socket.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -38,13 +42,26 @@ typedef struct chiaki_discovery_packet_t
char *protocol_version; char *protocol_version;
} ChiakiDiscoveryPacket; } ChiakiDiscoveryPacket;
CHIAKI_EXPORT int chiaki_discovery_packet_fmt(char *buf, size_t buf_size, ChiakiDiscoveryPacket *packet);
typedef struct chiaki_discovery_t typedef struct chiaki_discovery_t
{ {
int socket; int socket;
struct sockaddr local_addr;
} ChiakiDiscovery; } ChiakiDiscovery;
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_init(ChiakiDiscovery *discovery); CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_init(ChiakiDiscovery *discovery, sa_family_t family);
CHIAKI_EXPORT void chiaki_discovery_fini(ChiakiDiscovery *discovery); CHIAKI_EXPORT void chiaki_discovery_fini(ChiakiDiscovery *discovery);
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_send(ChiakiDiscovery *discovery, ChiakiDiscoveryPacket *packet, struct sockaddr *addr, size_t addr_size);
typedef struct chiaki_discovery_thread_t
{
ChiakiDiscovery *discovery;
ChiakiThread thread;
} ChiakiDiscoveryThread;
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_thread_start(ChiakiDiscoveryThread *thread);
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_thread_stop(ChiakiDiscoveryThread *thread);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -17,22 +17,60 @@
#include <chiaki/discovery.h> #include <chiaki/discovery.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <netdb.h>
#include <sys/types.h> #include <stdio.h>
#include <sys/socket.h>
static const char *packet_srch_template = CHIAKI_EXPORT int chiaki_discovery_packet_fmt(char *buf, size_t buf_size, ChiakiDiscoveryPacket *packet)
"SRCH * HTTP/1.1\n"
"device-discovery-protocol-version:%s\n";
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_init(ChiakiDiscovery *discovery)
{ {
const char *version_str = packet->protocol_version ? packet->protocol_version : CHIAKI_DISCOVERY_PROTOCOL_VERSION;
switch(packet->cmd)
{
case CHIAKI_DISCOVERY_CMD_SRCH:
return snprintf(buf, buf_size, "SRCH * HTTP/1.1\ndevice-discovery-protocol-version:%s\n",
version_str);
default:
return -1;
}
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_init(ChiakiDiscovery *discovery, sa_family_t family)
{
if(family != AF_INET && family != AF_INET6)
return CHIAKI_ERR_INVALID_DATA;
discovery->socket = socket(AF_INET, SOCK_DGRAM, 0); discovery->socket = socket(AF_INET, SOCK_DGRAM, 0);
if(discovery->socket < 0) if(discovery->socket < 0)
return CHIAKI_ERR_UNKNOWN; return CHIAKI_ERR_NETWORK;
memset(&discovery->local_addr, 0, sizeof(discovery->local_addr));
discovery->local_addr.sa_family = family;
if(family == AF_INET6)
{
struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&discovery->local_addr;
addr->sin6_addr = anyaddr;
addr->sin6_port = htons(0);
}
else // AF_INET
{
struct sockaddr_in *addr = (struct sockaddr_in *)&discovery->local_addr;
addr->sin_addr.s_addr = htonl(INADDR_ANY);
addr->sin_port = htons(0);
}
int r = bind(discovery->socket, &discovery->local_addr, sizeof(discovery->local_addr));
if(r < 0)
{
close(discovery->socket);
return CHIAKI_ERR_NETWORK;
}
const int broadcast = 1;
setsockopt(discovery->socket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
return CHIAKI_ERR_SUCCESS; return CHIAKI_ERR_SUCCESS;
} }
@ -40,3 +78,35 @@ CHIAKI_EXPORT void chiaki_discovery_fini(ChiakiDiscovery *discovery)
{ {
close(discovery->socket); close(discovery->socket);
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_send(ChiakiDiscovery *discovery, ChiakiDiscoveryPacket *packet, struct sockaddr *addr, size_t addr_size)
{
if(addr->sa_family != discovery->local_addr.sa_family)
return CHIAKI_ERR_INVALID_DATA;
char buf[512];
int len = chiaki_discovery_packet_fmt(buf, sizeof(buf), packet);
if(len < 0)
return CHIAKI_ERR_UNKNOWN;
if((size_t)len >= sizeof(buf))
return CHIAKI_ERR_BUF_TOO_SMALL;
ssize_t rc = sendto(discovery->socket, buf, (size_t)len + 1, 0, addr, addr_size);
if(rc < 0)
return CHIAKI_ERR_NETWORK;
return CHIAKI_ERR_SUCCESS;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_thread_start(ChiakiDiscoveryThread *thread)
{
// TODO
return CHIAKI_ERR_SUCCESS;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_thread_stop(ChiakiDiscoveryThread *thread)
{
// TODO
return CHIAKI_ERR_SUCCESS;
}