Add error logging capability
Need to test internal atostr function.
This commit is contained in:
parent
ff31b0f604
commit
faba06a2b6
2 changed files with 132 additions and 14 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
UDPC_Context* UDPC_init(uint16_t listenPort, int isClient)
|
UDPC_Context* UDPC_init(uint16_t listenPort, int isClient)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +11,7 @@ UDPC_Context* UDPC_init(uint16_t listenPort, int isClient)
|
||||||
context->error = UDPC_SUCCESS;
|
context->error = UDPC_SUCCESS;
|
||||||
context->flags = 0;
|
context->flags = 0;
|
||||||
context->threadFlags = 0;
|
context->threadFlags = 0;
|
||||||
|
context->atostrBuf[UDPC_ATOSTR_BUF_SIZE - 1] = 0;
|
||||||
if(isClient != 0) context->flags |= 0x2;
|
if(isClient != 0) context->flags |= 0x2;
|
||||||
|
|
||||||
// create socket
|
// create socket
|
||||||
|
@ -65,6 +68,8 @@ UDPC_Context* UDPC_init(uint16_t listenPort, int isClient)
|
||||||
|
|
||||||
timespec_get(&context->lastUpdated, TIME_UTC);
|
timespec_get(&context->lastUpdated, TIME_UTC);
|
||||||
|
|
||||||
|
context->flags |= (0x8 | 0x4);
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +174,31 @@ const char* UDPC_get_error_str(uint32_t error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDPC_set_logging_type(UDPC_Context *ctx, uint32_t logType)
|
||||||
|
{
|
||||||
|
switch(logType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ctx->flags &= 0xFFFFFFC3;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ctx->flags &= 0xFFFFFFC7;
|
||||||
|
ctx->flags |= 0x4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ctx->flags &= 0xFFFFFFCF;
|
||||||
|
ctx->flags |= (0x4 | 0x8);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ctx->flags &= 0xFFFFFFDF;
|
||||||
|
ctx->flags |= (0x4 | 0x8 | 0x10);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ctx->flags |= (0x4 | 0x8 | 0x10 | 0x20);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UDPC_update(UDPC_Context *ctx)
|
void UDPC_update(UDPC_Context *ctx)
|
||||||
{
|
{
|
||||||
// get dt
|
// get dt
|
||||||
|
@ -189,7 +219,9 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
if(UDPC_ts_diff_to_seconds(&tsNow, &cd->received) >= UDPC_TIMEOUT_SECONDS)
|
if(UDPC_ts_diff_to_seconds(&tsNow, &cd->received) >= UDPC_TIMEOUT_SECONDS)
|
||||||
{
|
{
|
||||||
UDPC_Deque_push_back(removedQueue, &x, sizeof(int));
|
UDPC_Deque_push_back(removedQueue, &x, sizeof(int));
|
||||||
// TODO log timed out connection
|
UDPC_INTERNAL_log(ctx, 2, "Connection timed out with addr %s port %d",
|
||||||
|
UDPC_INTERNAL_atostr(ctx, cd->addr),
|
||||||
|
cd->port);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +231,9 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
if((cd->flags & 0x2) != 0 && (cd->flags & 0x4) == 0)
|
if((cd->flags & 0x2) != 0 && (cd->flags & 0x4) == 0)
|
||||||
{
|
{
|
||||||
// good mode, bad rtt
|
// good mode, bad rtt
|
||||||
// TODO log switching to bad mode
|
UDPC_INTERNAL_log(ctx, 2, "Connection with %s switching to bad mode",
|
||||||
|
UDPC_INTERNAL_atostr(ctx, cd->addr));
|
||||||
|
|
||||||
cd->flags = cd->flags & 0xFFFFFFFD;
|
cd->flags = cd->flags & 0xFFFFFFFD;
|
||||||
if(cd->toggledTimer >= 10.0f)
|
if(cd->toggledTimer >= 10.0f)
|
||||||
{
|
{
|
||||||
|
@ -231,7 +265,8 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
{
|
{
|
||||||
cd->toggleTimer = 0.0f;
|
cd->toggleTimer = 0.0f;
|
||||||
cd->toggledTimer = 0.0f;
|
cd->toggledTimer = 0.0f;
|
||||||
// TODO log switching to good mode
|
UDPC_INTERNAL_log(ctx, 2, "Connection with %s switching to good mode",
|
||||||
|
UDPC_INTERNAL_atostr(ctx, cd->addr));
|
||||||
cd->flags |= 0x2;
|
cd->flags |= 0x2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,11 +310,11 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *data = malloc(20);
|
char *data = malloc(20);
|
||||||
UDPC_INTERNAL_prepare_pkt(data, cd->id, cd->rseq, cd->ack, &cd->lseq, cd->addr, 0);
|
UDPC_INTERNAL_prepare_pkt(data, cd->id, cd->rseq, cd->ack, &cd->lseq, 0);
|
||||||
|
|
||||||
struct sockaddr_in destinationInfo;
|
struct sockaddr_in destinationInfo;
|
||||||
destinationInfo.sin_family = AF_INET;
|
destinationInfo.sin_family = AF_INET;
|
||||||
destinationInfo.sin_addr.s_addr = htonl(cd->addr);
|
destinationInfo.sin_addr.s_addr = cd->addr;
|
||||||
destinationInfo.sin_port = htons(cd->port);
|
destinationInfo.sin_port = htons(cd->port);
|
||||||
long int sentBytes = sendto(
|
long int sentBytes = sendto(
|
||||||
ctx->socketHandle,
|
ctx->socketHandle,
|
||||||
|
@ -290,7 +325,8 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
sizeof(struct sockaddr_in));
|
sizeof(struct sockaddr_in));
|
||||||
if(sentBytes != 20)
|
if(sentBytes != 20)
|
||||||
{
|
{
|
||||||
// TODO log fail send packet
|
UDPC_INTERNAL_log(ctx, 0, "Failed to send packet to %s port %s",
|
||||||
|
UDPC_INTERNAL_atostr(ctx, cd->addr), cd->port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -322,12 +358,12 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(
|
UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(
|
||||||
cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
|
cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
|
||||||
char *data = malloc(20 + pinfo->size);
|
char *data = malloc(20 + pinfo->size);
|
||||||
UDPC_INTERNAL_prepare_pkt(data, cd->id, cd->rseq, cd->ack, &cd->lseq, cd->addr, ((pinfo->flags & 0x3) << 1));
|
UDPC_INTERNAL_prepare_pkt(data, cd->id, cd->rseq, cd->ack, &cd->lseq, ((pinfo->flags & 0x3) << 1));
|
||||||
memcpy(&data[20], pinfo->data, pinfo->size);
|
memcpy(&data[20], pinfo->data, pinfo->size);
|
||||||
|
|
||||||
struct sockaddr_in destinationInfo;
|
struct sockaddr_in destinationInfo;
|
||||||
destinationInfo.sin_family = AF_INET;
|
destinationInfo.sin_family = AF_INET;
|
||||||
destinationInfo.sin_addr.s_addr = htonl(cd->addr);
|
destinationInfo.sin_addr.s_addr = cd->addr;
|
||||||
destinationInfo.sin_port = htons(cd->port);
|
destinationInfo.sin_port = htons(cd->port);
|
||||||
long int sentBytes = sendto(
|
long int sentBytes = sendto(
|
||||||
ctx->socketHandle,
|
ctx->socketHandle,
|
||||||
|
@ -338,7 +374,8 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
sizeof(struct sockaddr_in));
|
sizeof(struct sockaddr_in));
|
||||||
if(sentBytes != 20 + pinfo->size)
|
if(sentBytes != 20 + pinfo->size)
|
||||||
{
|
{
|
||||||
// TODO log fail sent packet
|
UDPC_INTERNAL_log(ctx, 0, "Failed to send packet to %s port %s",
|
||||||
|
UDPC_INTERNAL_atostr(ctx, cd->addr), cd->port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -347,7 +384,7 @@ void UDPC_update(UDPC_Context *ctx)
|
||||||
UDPC_INTERNAL_PacketInfo sentInfo = {
|
UDPC_INTERNAL_PacketInfo sentInfo = {
|
||||||
cd->addr,
|
cd->addr,
|
||||||
cd->lseq - 1,
|
cd->lseq - 1,
|
||||||
pinfo->flags & 0x2,
|
0x2,
|
||||||
data,
|
data,
|
||||||
20 + pinfo->size,
|
20 + pinfo->size,
|
||||||
tsNow
|
tsNow
|
||||||
|
@ -473,7 +510,6 @@ void UDPC_INTERNAL_prepare_pkt(
|
||||||
uint32_t rseq,
|
uint32_t rseq,
|
||||||
uint32_t ack,
|
uint32_t ack,
|
||||||
uint32_t *seqID,
|
uint32_t *seqID,
|
||||||
uint32_t addr,
|
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
char *d = data;
|
char *d = data;
|
||||||
|
@ -504,3 +540,59 @@ void UDPC_INTERNAL_prepare_pkt(
|
||||||
temp = htonl(ack);
|
temp = htonl(ack);
|
||||||
memcpy(&d[16], &temp, 4);
|
memcpy(&d[16], &temp, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDPC_INTERNAL_log(UDPC_Context *ctx, uint32_t level, const char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, msg);
|
||||||
|
switch(level)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
if((ctx->flags & 0x4) == 0) break;
|
||||||
|
fprintf(stderr, "ERR: ");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if((ctx->flags & 0x8) == 0) break;
|
||||||
|
fprintf(stderr, "WARN: ");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if((ctx->flags & 0x10) == 0) break;
|
||||||
|
fprintf(stderr, "INFO: ");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if((ctx->flags & 0x20) == 0) break;
|
||||||
|
fprintf(stderr, "VERBOSE: ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vfprintf(stderr, msg, args);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* UDPC_INTERNAL_atostr(UDPC_Context *ctx, uint32_t addr)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for(int x = 0; x < 4; ++x)
|
||||||
|
{
|
||||||
|
unsigned char temp = (addr >> (24 - x * 8)) & 0xFF;
|
||||||
|
|
||||||
|
if(temp >= 100)
|
||||||
|
{
|
||||||
|
ctx->atostrBuf[index++] = '0' + temp / 100;
|
||||||
|
}
|
||||||
|
if(temp >= 10)
|
||||||
|
{
|
||||||
|
ctx->atostrBuf[index++] = '0' + ((temp / 10) % 10);
|
||||||
|
}
|
||||||
|
ctx->atostrBuf[index++] = '0' + temp % 10;
|
||||||
|
|
||||||
|
if(x < 3)
|
||||||
|
{
|
||||||
|
ctx->atostrBuf[index++] = '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx->atostrBuf[index] = 0;
|
||||||
|
|
||||||
|
return ctx->atostrBuf;
|
||||||
|
}
|
||||||
|
|
|
@ -24,11 +24,12 @@
|
||||||
#define CleanupSocket(x) ((void)0)
|
#define CleanupSocket(x) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UDPC_ATOSTR_BUF_SIZE 16
|
||||||
|
|
||||||
/// This struct should not be used outside of this library
|
/// This struct should not be used outside of this library
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t addr;
|
uint32_t addr; // in network order (big-endian)
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
/*
|
/*
|
||||||
* 0x1 - is resending
|
* 0x1 - is resending
|
||||||
|
@ -58,7 +59,7 @@ typedef struct
|
||||||
float toggleT;
|
float toggleT;
|
||||||
float toggleTimer;
|
float toggleTimer;
|
||||||
float toggledTimer;
|
float toggledTimer;
|
||||||
uint32_t addr;
|
uint32_t addr; // in network order (big-endian)
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
UDPC_Deque *sentPkts;
|
UDPC_Deque *sentPkts;
|
||||||
UDPC_Deque *sendPktQueue;
|
UDPC_Deque *sendPktQueue;
|
||||||
|
@ -73,6 +74,10 @@ typedef struct
|
||||||
/*
|
/*
|
||||||
* 0x1 - is threaded
|
* 0x1 - is threaded
|
||||||
* 0x2 - is client
|
* 0x2 - is client
|
||||||
|
* 0x4 - log errors
|
||||||
|
* 0x8 - log warnings
|
||||||
|
* 0x10 - log info
|
||||||
|
* 0x20 - log verbose
|
||||||
*/
|
*/
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
/*
|
/*
|
||||||
|
@ -88,6 +93,7 @@ typedef struct
|
||||||
cnd_t threadCV;
|
cnd_t threadCV;
|
||||||
UDPC_Deque *connected;
|
UDPC_Deque *connected;
|
||||||
struct timespec lastUpdated;
|
struct timespec lastUpdated;
|
||||||
|
char atostrBuf[UDPC_ATOSTR_BUF_SIZE];
|
||||||
} UDPC_Context;
|
} UDPC_Context;
|
||||||
|
|
||||||
UDPC_Context* UDPC_init(uint16_t listenPort, int isClient);
|
UDPC_Context* UDPC_init(uint16_t listenPort, int isClient);
|
||||||
|
@ -100,6 +106,17 @@ uint32_t UDPC_get_error(UDPC_Context *ctx);
|
||||||
|
|
||||||
const char* UDPC_get_error_str(uint32_t error);
|
const char* UDPC_get_error_str(uint32_t error);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* 0 - log nothing
|
||||||
|
* 1 - log only errors
|
||||||
|
* 2 - log only errors and warnings
|
||||||
|
* 3 - log errors, warnings, and info
|
||||||
|
* 4+ - log everything
|
||||||
|
*
|
||||||
|
* By default, erros and warnings are logged.
|
||||||
|
*/
|
||||||
|
void UDPC_set_logging_type(UDPC_Context *ctx, uint32_t logType);
|
||||||
|
|
||||||
/// If threaded, this function is called automatically
|
/// If threaded, this function is called automatically
|
||||||
void UDPC_update(UDPC_Context *ctx);
|
void UDPC_update(UDPC_Context *ctx);
|
||||||
|
|
||||||
|
@ -118,7 +135,16 @@ void UDPC_INTERNAL_prepare_pkt(
|
||||||
uint32_t rseq,
|
uint32_t rseq,
|
||||||
uint32_t ack,
|
uint32_t ack,
|
||||||
uint32_t *seqID,
|
uint32_t *seqID,
|
||||||
uint32_t addr,
|
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* 0 - error
|
||||||
|
* 1 - warning
|
||||||
|
* 2 - info
|
||||||
|
* 3 - verbose
|
||||||
|
*/
|
||||||
|
void UDPC_INTERNAL_log(UDPC_Context *ctx, uint32_t level, const char *msg, ...);
|
||||||
|
|
||||||
|
char* UDPC_INTERNAL_atostr(UDPC_Context *ctx, uint32_t addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue