2019-06-06 07:02:48 +00:00
|
|
|
#include "UDPC_Defines.hpp"
|
2019-06-06 07:42:07 +00:00
|
|
|
#include "UDPConnection.h"
|
2019-06-06 07:02:48 +00:00
|
|
|
|
2019-07-07 05:44:37 +00:00
|
|
|
#include <optional>
|
|
|
|
|
2019-06-06 07:42:07 +00:00
|
|
|
UDPC::Context::Context(bool isThreaded)
|
|
|
|
: _contextIdentifier(UDPC_CONTEXT_IDENTIFIER), flags(),
|
|
|
|
isAcceptNewConnections(true), protocolID(UDPC_DEFAULT_PROTOCOL_ID),
|
2019-06-06 07:02:48 +00:00
|
|
|
#ifndef NDEBUG
|
2019-06-06 07:42:07 +00:00
|
|
|
loggingType(INFO)
|
2019-06-06 07:02:48 +00:00
|
|
|
#else
|
2019-06-06 07:42:07 +00:00
|
|
|
loggingType(WARNING)
|
2019-06-06 07:02:48 +00:00
|
|
|
#endif
|
|
|
|
{
|
2019-07-21 04:45:42 +00:00
|
|
|
if(isThreaded) {
|
2019-06-06 07:02:48 +00:00
|
|
|
flags.set(0);
|
|
|
|
} else {
|
|
|
|
flags.reset(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *UDPC::verifyContext(void *ctx) {
|
|
|
|
if(ctx == nullptr) {
|
|
|
|
return nullptr;
|
2019-06-06 07:02:48 +00:00
|
|
|
}
|
2019-06-06 07:42:07 +00:00
|
|
|
UDPC::Context *c = (UDPC::Context *)ctx;
|
2019-07-21 04:45:42 +00:00
|
|
|
if(c->_contextIdentifier == UDPC_CONTEXT_IDENTIFIER) {
|
|
|
|
return c;
|
2019-06-06 07:02:48 +00:00
|
|
|
} else {
|
2019-07-21 04:45:42 +00:00
|
|
|
return nullptr;
|
2019-06-06 07:02:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-07 05:44:37 +00:00
|
|
|
bool UDPC::isBigEndian() {
|
2019-07-07 05:48:58 +00:00
|
|
|
static std::optional<bool> isBigEndian = std::nullopt;
|
2019-07-07 05:44:37 +00:00
|
|
|
if(isBigEndian) {
|
|
|
|
return *isBigEndian;
|
|
|
|
}
|
|
|
|
union {
|
|
|
|
uint32_t i;
|
|
|
|
char c[4];
|
2019-07-21 04:45:42 +00:00
|
|
|
} bint = {0x01020304};
|
2019-07-07 05:44:37 +00:00
|
|
|
|
|
|
|
isBigEndian = (bint.c[0] == 1);
|
|
|
|
return *isBigEndian;
|
|
|
|
}
|
|
|
|
|
2019-06-06 07:42:07 +00:00
|
|
|
void *UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient) {
|
2019-06-06 07:02:48 +00:00
|
|
|
UDPC::Context *ctx = new UDPC::Context(false);
|
|
|
|
|
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
2019-06-06 07:42:07 +00:00
|
|
|
void *UDPC_init_threaded_update(uint16_t listenPort, uint32_t listenAddr,
|
|
|
|
int isClient) {
|
2019-06-06 07:02:48 +00:00
|
|
|
UDPC::Context *ctx = new UDPC::Context(true);
|
|
|
|
|
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void UDPC_destroy(void *ctx) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *UDPC_ctx = UDPC::verifyContext(ctx);
|
|
|
|
if(UDPC_ctx) {
|
|
|
|
delete UDPC_ctx;
|
2019-06-06 07:02:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UDPC_update(void *ctx) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-07-21 04:45:42 +00:00
|
|
|
if(c->flags.test(0)) {
|
2019-06-06 07:02:48 +00:00
|
|
|
// is threaded, update should not be called
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO impl
|
|
|
|
}
|
|
|
|
|
|
|
|
int UDPC_get_queue_send_available(void *ctx, uint32_t addr) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// TODO impl
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-06-06 07:42:07 +00:00
|
|
|
void UDPC_queue_send(void *ctx, uint32_t destAddr, uint16_t destPort,
|
|
|
|
uint32_t isChecked, void *data, uint32_t size) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// TODO impl
|
|
|
|
}
|
|
|
|
|
|
|
|
int UDPC_set_accept_new_connections(void *ctx, int isAccepting) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return c->isAcceptNewConnections.exchange(isAccepting == 0 ? false : true);
|
|
|
|
}
|
|
|
|
|
|
|
|
int UDPC_drop_connection(void *ctx, uint32_t addr, uint16_t port) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// TODO impl
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t UDPC_set_protocol_id(void *ctx, uint32_t id) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return c->protocolID.exchange(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
UDPC_LoggingType set_logging_type(void *ctx, UDPC_LoggingType loggingType) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return static_cast<UDPC_LoggingType>(0);
|
|
|
|
}
|
|
|
|
return static_cast<UDPC_LoggingType>(c->loggingType.exchange(loggingType));
|
|
|
|
}
|
|
|
|
|
|
|
|
PacketInfo UDPC_get_received(void *ctx) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return PacketInfo{{0}, 0, 0, 0, 0, 0};
|
|
|
|
}
|
|
|
|
// TODO impl
|
|
|
|
return PacketInfo{{0}, 0, 0, 0, 0, 0};
|
|
|
|
}
|
|
|
|
|
2019-06-06 07:42:07 +00:00
|
|
|
const char *UDPC_atostr(void *ctx, uint32_t addr) {
|
2019-07-21 04:45:42 +00:00
|
|
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
|
|
|
if(!c) {
|
2019-06-06 07:02:48 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
int index = 0;
|
2019-07-21 04:45:42 +00:00
|
|
|
for(int x = 0; x < 4; ++x) {
|
2019-06-06 07:02:48 +00:00
|
|
|
unsigned char temp = (addr >> (x * 8)) & 0xFF;
|
|
|
|
|
2019-07-21 04:45:42 +00:00
|
|
|
if(temp >= 100) {
|
2019-06-06 07:02:48 +00:00
|
|
|
c->atostrBuf[index++] = '0' + temp / 100;
|
|
|
|
}
|
2019-07-21 04:45:42 +00:00
|
|
|
if(temp >= 10) {
|
2019-06-06 07:02:48 +00:00
|
|
|
c->atostrBuf[index++] = '0' + ((temp / 10) % 10);
|
|
|
|
}
|
|
|
|
c->atostrBuf[index++] = '0' + temp % 10;
|
|
|
|
|
2019-07-21 04:45:42 +00:00
|
|
|
if(x < 3) {
|
2019-06-06 07:02:48 +00:00
|
|
|
c->atostrBuf[index++] = '.';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c->atostrBuf[index] = 0;
|
|
|
|
|
|
|
|
return c->atostrBuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t UDPC_strtoa(const char *addrStr) {
|
|
|
|
uint32_t addr = 0;
|
|
|
|
uint32_t temp = 0;
|
|
|
|
uint32_t index = 0;
|
2019-07-21 04:45:42 +00:00
|
|
|
while(*addrStr != 0) {
|
|
|
|
if(*addrStr >= '0' && *addrStr <= '9') {
|
2019-06-06 07:02:48 +00:00
|
|
|
temp *= 10;
|
|
|
|
temp += *addrStr - '0';
|
2019-07-21 04:45:42 +00:00
|
|
|
} else if(*addrStr == '.' && temp <= 0xFF && index < 3) {
|
2019-07-07 05:44:37 +00:00
|
|
|
if(UDPC::isBigEndian()) {
|
|
|
|
addr |= (temp << (24 - 8 * index++));
|
|
|
|
} else {
|
|
|
|
addr |= (temp << (8 * index++));
|
|
|
|
}
|
2019-06-06 07:02:48 +00:00
|
|
|
temp = 0;
|
2019-06-06 07:42:07 +00:00
|
|
|
} else {
|
2019-06-06 07:02:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
++addrStr;
|
|
|
|
}
|
|
|
|
|
2019-07-21 04:45:42 +00:00
|
|
|
if(index == 3 && temp <= 0xFF) {
|
2019-07-07 05:44:37 +00:00
|
|
|
if(UDPC::isBigEndian()) {
|
|
|
|
addr |= temp;
|
|
|
|
} else {
|
|
|
|
addr |= temp << 24;
|
|
|
|
}
|
2019-06-06 07:02:48 +00:00
|
|
|
return addr;
|
2019-06-06 07:42:07 +00:00
|
|
|
} else {
|
2019-06-06 07:02:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|