]> git.seodisparate.com - UDPConnection/commitdiff
Add error logging capability
authorStephen Seo <seo.disparate@gmail.com>
Fri, 1 Feb 2019 10:22:04 +0000 (19:22 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Fri, 1 Feb 2019 10:22:04 +0000 (19:22 +0900)
Need to test internal atostr function.

src/UDPConnection.c
src/UDPConnection.h

index 4debe47b090902cef6c836732c4af03cf2b65dba..c5fae0e6e7e7c0498315e126b63d9abbc34404cf 100644 (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;
+}
index d6ae457f0a18f6df4d1e93c0a1e2c2c7812c83bc..ee32a3d41434690dfa59885ea9537af10816714d 100644 (file)
   #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