Add error logging capability

Need to test internal atostr function.
This commit is contained in:
Stephen Seo 2019-02-01 19:22:04 +09:00
parent ff31b0f604
commit faba06a2b6
2 changed files with 132 additions and 14 deletions

View file

@ -2,6 +2,8 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
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->flags = 0;
context->threadFlags = 0;
context->atostrBuf[UDPC_ATOSTR_BUF_SIZE - 1] = 0;
if(isClient != 0) context->flags |= 0x2;
// create socket
@ -65,6 +68,8 @@ UDPC_Context* UDPC_init(uint16_t listenPort, int isClient)
timespec_get(&context->lastUpdated, TIME_UTC);
context->flags |= (0x8 | 0x4);
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)
{
// get dt
@ -189,7 +219,9 @@ void UDPC_update(UDPC_Context *ctx)
if(UDPC_ts_diff_to_seconds(&tsNow, &cd->received) >= UDPC_TIMEOUT_SECONDS)
{
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;
}
@ -199,7 +231,9 @@ void UDPC_update(UDPC_Context *ctx)
if((cd->flags & 0x2) != 0 && (cd->flags & 0x4) == 0)
{
// 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;
if(cd->toggledTimer >= 10.0f)
{
@ -231,7 +265,8 @@ void UDPC_update(UDPC_Context *ctx)
{
cd->toggleTimer = 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;
}
}
@ -275,11 +310,11 @@ void UDPC_update(UDPC_Context *ctx)
}
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;
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);
long int sentBytes = sendto(
ctx->socketHandle,
@ -290,7 +325,8 @@ void UDPC_update(UDPC_Context *ctx)
sizeof(struct sockaddr_in));
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
{
@ -322,12 +358,12 @@ void UDPC_update(UDPC_Context *ctx)
UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(
cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
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);
struct sockaddr_in destinationInfo;
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);
long int sentBytes = sendto(
ctx->socketHandle,
@ -338,7 +374,8 @@ void UDPC_update(UDPC_Context *ctx)
sizeof(struct sockaddr_in));
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
{
@ -347,7 +384,7 @@ void UDPC_update(UDPC_Context *ctx)
UDPC_INTERNAL_PacketInfo sentInfo = {
cd->addr,
cd->lseq - 1,
pinfo->flags & 0x2,
0x2,
data,
20 + pinfo->size,
tsNow
@ -473,7 +510,6 @@ void UDPC_INTERNAL_prepare_pkt(
uint32_t rseq,
uint32_t ack,
uint32_t *seqID,
uint32_t addr,
int flags)
{
char *d = data;
@ -504,3 +540,59 @@ void UDPC_INTERNAL_prepare_pkt(
temp = htonl(ack);
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;
}

View file

@ -24,11 +24,12 @@
#define CleanupSocket(x) ((void)0)
#endif
#define UDPC_ATOSTR_BUF_SIZE 16
/// This struct should not be used outside of this library
typedef struct
{
uint32_t addr;
uint32_t addr; // in network order (big-endian)
uint32_t id;
/*
* 0x1 - is resending
@ -58,7 +59,7 @@ typedef struct
float toggleT;
float toggleTimer;
float toggledTimer;
uint32_t addr;
uint32_t addr; // in network order (big-endian)
uint16_t port;
UDPC_Deque *sentPkts;
UDPC_Deque *sendPktQueue;
@ -73,6 +74,10 @@ typedef struct
/*
* 0x1 - is threaded
* 0x2 - is client
* 0x4 - log errors
* 0x8 - log warnings
* 0x10 - log info
* 0x20 - log verbose
*/
uint32_t flags;
/*
@ -88,6 +93,7 @@ typedef struct
cnd_t threadCV;
UDPC_Deque *connected;
struct timespec lastUpdated;
char atostrBuf[UDPC_ATOSTR_BUF_SIZE];
} UDPC_Context;
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);
/*!
* 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
void UDPC_update(UDPC_Context *ctx);
@ -118,7 +135,16 @@ void UDPC_INTERNAL_prepare_pkt(
uint32_t rseq,
uint32_t ack,
uint32_t *seqID,
uint32_t addr,
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