UDPConnection/cpp_impl/src/UDPConnection.cpp

200 lines
4.7 KiB
C++
Raw Normal View History

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
#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-06-06 07:42:07 +00:00
if (isThreaded) {
2019-06-06 07:02:48 +00:00
flags.set(0);
} else {
flags.reset(0);
}
}
bool UDPC::VerifyContext(void *ctx) {
2019-06-06 07:42:07 +00:00
if (ctx == nullptr) {
2019-06-06 07:02:48 +00:00
return false;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
if (c->_contextIdentifier == UDPC_CONTEXT_IDENTIFIER) {
2019-06-06 07:02:48 +00:00
return true;
} else {
return false;
}
}
bool UDPC::isBigEndian() {
static std::optional<bool> isBigEndian = {};
if(isBigEndian) {
return *isBigEndian;
}
union {
uint32_t i;
char c[4];
} bint = { 0x01020304 };
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) {
if (UDPC::VerifyContext(ctx)) {
2019-06-06 07:42:07 +00:00
delete (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
}
}
void UDPC_update(void *ctx) {
2019-06-06 07:42:07 +00:00
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
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-06-06 07:42:07 +00:00
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return 0;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
// 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) {
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
// TODO impl
}
int UDPC_set_accept_new_connections(void *ctx, int isAccepting) {
2019-06-06 07:42:07 +00:00
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return 0;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
return c->isAcceptNewConnections.exchange(isAccepting == 0 ? false : true);
}
int UDPC_drop_connection(void *ctx, uint32_t addr, uint16_t port) {
2019-06-06 07:42:07 +00:00
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return 0;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
// TODO impl
return 0;
}
uint32_t UDPC_set_protocol_id(void *ctx, uint32_t id) {
2019-06-06 07:42:07 +00:00
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return 0;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
return c->protocolID.exchange(id);
}
UDPC_LoggingType set_logging_type(void *ctx, UDPC_LoggingType loggingType) {
2019-06-06 07:42:07 +00:00
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return static_cast<UDPC_LoggingType>(0);
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
return static_cast<UDPC_LoggingType>(c->loggingType.exchange(loggingType));
}
PacketInfo UDPC_get_received(void *ctx) {
2019-06-06 07:42:07 +00:00
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return PacketInfo{{0}, 0, 0, 0, 0, 0};
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
// 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) {
if (!UDPC::VerifyContext(ctx)) {
2019-06-06 07:02:48 +00:00
return nullptr;
}
2019-06-06 07:42:07 +00:00
UDPC::Context *c = (UDPC::Context *)ctx;
2019-06-06 07:02:48 +00:00
int index = 0;
2019-06-06 07:42:07 +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-06-06 07:42:07 +00:00
if (temp >= 100) {
2019-06-06 07:02:48 +00:00
c->atostrBuf[index++] = '0' + temp / 100;
}
2019-06-06 07:42:07 +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-06-06 07:42:07 +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-06-06 07:42:07 +00:00
while (*addrStr != 0) {
if (*addrStr >= '0' && *addrStr <= '9') {
2019-06-06 07:02:48 +00:00
temp *= 10;
temp += *addrStr - '0';
2019-06-06 07:42:07 +00:00
} else if (*addrStr == '.' && temp <= 0xFF && index < 3) {
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-06-06 07:42:07 +00:00
if (index == 3 && temp <= 0xFF) {
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;
}
}