From 1654523577709582fbd68f6d55cdaa5d13ed8743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiesner=20Andr=C3=A1s?= Date: Thu, 3 Nov 2022 07:47:10 +0100 Subject: [PATCH] PcktRegistry initial steps --- Doxyfile | 18 +++++++++--------- common_types.h | 2 +- dynmem.c | 22 ++++++++++++++++++++++ dynmem.h | 25 +++++++++++++++++++++++++ global_state.c | 8 ++++++++ global_state.h | 23 +++++++++++++++++++++++ memory_pool.c | 2 +- memory_pool.h | 2 +- packet_registry.c | 42 ++++++++++++++++++++++++++++++++++++++---- packet_registry.h | 36 ++++++++++++++++++++++++++++-------- utils.h | 2 ++ 11 files changed, 158 insertions(+), 24 deletions(-) create mode 100644 dynmem.c create mode 100644 dynmem.h create mode 100644 global_state.c create mode 100644 global_state.h diff --git a/Doxyfile b/Doxyfile index c89a384..a545e37 100644 --- a/Doxyfile +++ b/Doxyfile @@ -316,7 +316,7 @@ OPTIMIZE_OUTPUT_SLICE = NO # Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files +# default for Fortran class files). For instance to make doxygen treat .inc files # as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. # @@ -385,7 +385,7 @@ SIP_SUPPORT = NO # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you +# class. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. @@ -406,9 +406,9 @@ DISTRIBUTE_GROUP_DOC = NO GROUP_NESTED_COMPOUNDS = NO -# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# Set the SUBGROUPING tag to YES to allow class member groups of the same class # (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent +# class (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. @@ -680,7 +680,7 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between +# class resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still @@ -1153,7 +1153,7 @@ VERBATIM_HEADERS = YES # clang parser (see: # http://clang.llvm.org/) for more accurate parsing at the cost of reduced # performance. This can be particularly helpful with template rich C++ code for -# which doxygen's built-in parser lacks the necessary type information. +# which doxygen's built-in parser lacks the necessary class information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. @@ -1840,7 +1840,7 @@ LATEX_MAKEINDEX_CMD = makeindex COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used by the +# The PAPER_TYPE tag can be used to set the paper class that is used by the # printer. # Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x # 14 inches) and executive (7.25 x 10.5 inches). @@ -2429,7 +2429,7 @@ UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside the # class node. If there are many fields or methods and many nodes the graph may # become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the -# number of items for each type to make the size more manageable. Set this to 0 +# number of items for each class to make the size more manageable. Set this to 0 # for no limit. Note that the threshold may be exceeded by 50% before the limit # is enforced. So when you set the threshold to 10, up to 15 fields may appear, # but if the number exceeds 15, the total amount of fields shown is limited to @@ -2441,7 +2441,7 @@ UML_LIMIT_NUM_FIELDS = 10 # If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and # methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS -# tag is set to YES, doxygen will add type and arguments for attributes and +# tag is set to YES, doxygen will add class and arguments for attributes and # methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen # will not generate fields with class member information in the UML graphs. The # class diagrams will look similar to the default class diagrams but using UML diff --git a/common_types.h b/common_types.h index cdcfaaf..50e5c33 100644 --- a/common_types.h +++ b/common_types.h @@ -25,7 +25,7 @@ typedef struct { uint8_t * payload; ///< Pointer to (innermost) payload. uint16_t headerSize; ///< Packet header size in bytes. uint16_t payloadSize; ///< Payload size in bytes. - uint16_t type; ///< Packet type indicator (e.g. UDP, TCP, IPv4 etc.) + uint16_t type; ///< Packet class indicator (e.g. UDP, TCP, IPv4 etc.) } Pckt; #endif //ETHERLIB_COMMON_TYPES_H diff --git a/dynmem.c b/dynmem.c new file mode 100644 index 0000000..2d8788e --- /dev/null +++ b/dynmem.c @@ -0,0 +1,22 @@ +#include "dynmem.h" +#include "global_state.h" +#include "utils.h" + +#if !defined(ETHLIB_MEMORY_POOL_ATTRIBUTES) || (ETHLIB_MEMORY_POOL_ATTRIBUTES == none) + static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE]; +#elif + static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE] __attribute__((ETHLIB_MEMORY_POOL_ATTRIBUTES)); +#endif + +void dynmem_init() { + E.mp = mp_init(sDynMemPool, ETHLIB_MEMORY_POOL_TOTAL_SIZE); + ASSERT_NULL(E.mp); +} + +void * dynmem_alloc(uint32_t size) { + return mp_alloc(E.mp, size); +} + +void dynmem_free(void * ptr) { + mp_free(E.mp, ptr); +} \ No newline at end of file diff --git a/dynmem.h b/dynmem.h new file mode 100644 index 0000000..040aa80 --- /dev/null +++ b/dynmem.h @@ -0,0 +1,25 @@ +#ifndef ETHERLIB_DYNMEM_H +#define ETHERLIB_DYNMEM_H + +#include + +/** + * Initialize EtherLib dynamic memory management subsystem, + * based on heap pointer and size given in etherlib_options.h + */ +void dynmem_init(); + +/** + * Dynamically allocate memory from EtherLib's pool. + * @param size requested size + * @return pointer to allocated area or NULL on failure + */ +void * dynmem_alloc(uint32_t size); + +/** + * Release allocated block. + * @param ptr pointer to allocated area + */ +void dynmem_free(void * ptr); + +#endif //ETHERLIB_DYNMEM_H diff --git a/global_state.c b/global_state.c new file mode 100644 index 0000000..ba8de69 --- /dev/null +++ b/global_state.c @@ -0,0 +1,8 @@ +#include "global_state.h" +#include "dynmem.h" + +EthState gEthState; + +void ethlib_init() { + dynmem_init(); // initialize dynamic memory subsystem +} \ No newline at end of file diff --git a/global_state.h b/global_state.h new file mode 100644 index 0000000..2b9e1c8 --- /dev/null +++ b/global_state.h @@ -0,0 +1,23 @@ +#ifndef ETHERLIB_GLOBAL_STATE_H +#define ETHERLIB_GLOBAL_STATE_H + +#include "memory_pool.h" +#include "packet_registry.h" + +/** + * Global EtherLib state. + */ +typedef struct { + MP * mp; ///< Memory pool for synamic allocations. + PcktRegistry pcktReg; ///< Packet registry. +} EthState; + +extern EthState gEthState; +#define E (gEthState) + +/** + * Initialize EthLib. + */ +void ethlib_init(); + +#endif //ETHERLIB_GLOBAL_STATE_H diff --git a/memory_pool.c b/memory_pool.c index 97d91ab..e3ed283 100644 --- a/memory_pool.c +++ b/memory_pool.c @@ -54,7 +54,7 @@ uint8_t *mp_alloc(MP *mp, uint32_t size) { // allocate block uint8_t * ptr = NULL; - if (leastBadness == 0) { // just change block registry type if block perfectly fits + if (leastBadness == 0) { // just change block registry class if block perfectly fits bestBlock->type = MPRT_ALLOCATED; ptr = bestBlock->addrStart; } else { // if there are some bytes left between allocated blocks diff --git a/memory_pool.h b/memory_pool.h index 80a939e..84ecea2 100644 --- a/memory_pool.h +++ b/memory_pool.h @@ -6,7 +6,7 @@ #include /** - * Record type + * Record class */ typedef enum { MPRT_FREE = 0, diff --git a/packet_registry.c b/packet_registry.c index 3cd3ac2..23877fb 100644 --- a/packet_registry.c +++ b/packet_registry.c @@ -1,5 +1,39 @@ -// -// Created by epagris on 2022.10.18.. -// - #include "packet_registry.h" +#include "global_state.h" +#include "dynmem.h" +#include "utils.h" + +#include +#include + +#define PCKTREG_INITIAL_RESERVED_CNT (6) + +PcktRegistry * packreg_new() { + PcktRegistry * packReg = (PcktRegistry *)dynmem_alloc(sizeof(PcktRegistry)); + ASSERT_NULL(packReg); + packReg->reservedCnt = PCKTREG_INITIAL_RESERVED_CNT; + packReg->ents = (PcktClassDesc *) dynmem_alloc(sizeof(PcktClassDesc) * packReg->reservedCnt); + ASSERT_NULL(packReg->ents); + packReg->entCnt = 0; + return packReg; +} + +void packreg_add(PcktRegistry * packReg, const PcktClassDesc * classDesc) { + // if buffer is full and reallocation and resize is needed + if (packReg->reservedCnt == packReg->entCnt) { + PcktClassDesc * newEnts = (PcktClassDesc *) dynmem_alloc(packReg->reservedCnt * 2); + ASSERT_NULL(newEnts); + memcpy(newEnts, packReg->ents, packReg->reservedCnt * sizeof(PcktClassDesc)); + PcktClassDesc * oldEnts = packReg->ents; + packReg->ents = newEnts; + dynmem_free(oldEnts); + } + + // append new item + packReg->ents[packReg->entCnt] = *classDesc; + packReg->entCnt++; +} + +void packreg_get_by_class(uint16_t class) { + +} \ No newline at end of file diff --git a/packet_registry.h b/packet_registry.h index c10862c..a328617 100644 --- a/packet_registry.h +++ b/packet_registry.h @@ -19,7 +19,7 @@ typedef uint8_t bool8_t; */ typedef struct { uint16_t headerSize; ///< Header size in bytes - uint16_t containedPacketID; ///< ID of contained packet. Zero if no packet contained. + uint16_t containedPacketClass; ///< ID of contained packet. Zero if no packet contained. bool8_t checksumOK; ///< Indicates that checksum is OK. } PcktProps; @@ -30,25 +30,45 @@ typedef struct { * @param size: remaining packet size counted from pHdr * @param pPcktProps: pointer to existing structure to store * packet properties to (e.g. source address, port etc.) - * @return packet type of contained packet, or -1 on failure or + * @return packet class of contained packet, or -1 on failure or * 0 if no more standard packet contained (e.g. UDP packet contains * user data) */ typedef int (*PcktProcFn)(const uint8_t *pHdr, uint32_t size, uint8_t *pProps); /** - * @struct PcktTypeDesc - * Pckt type descriptor. Pckt parsers can be registered - * using PcktTypeDesc assignments. + * @struct PcktClassDesc + * Pckt class descriptor. Pckt parsers can be registered + * using PcktClassDesc assignments. */ typedef struct { - uint16_t type; ///< Type identification of the packet 'class' (unique!) - uint16_t containerType; ///< Type of container packet packet (e.g.: IPv4 in case of UDP) + uint16_t class; ///< Type identification of the packet 'class' (unique!) + uint16_t containerClass; ///< Type of container packet packet (e.g.: IPv4 in case of UDP) PcktProcFn procFun; ///< Pckt processing function -} PcktTypeDesc; +} PcktClassDesc; + +/** + * @struct PcktRegistry + * Packet registry sturcture. + */ +typedef struct { + PcktClassDesc * ents; ///< Packet registry entries + uint16_t entCnt; ///< Number of registry entries + uint16_t reservedCnt; ///< Buffer reservation in elements. +} PcktRegistry; // --------------------- +/** + * Create new packet registry + */ +PcktRegistry * packreg_new(); + +/** + * Add new packet class. (e.g. UDP, IP...) + * @param classDesc Packet class descriptor + */ +void packreg_add(PcktRegistry * packReg, const PcktClassDesc * classDesc); #endif //ETHERLIB_PACKET_REGISTRY_H \ No newline at end of file diff --git a/utils.h b/utils.h index b6fb7b6..7050170 100644 --- a/utils.h +++ b/utils.h @@ -11,6 +11,8 @@ #define INFO(...) printf(__VA_ARGS__) #define ASSERT_BAD_ALIGN(p) if ((size_t)(p) & 0b11) ERROR("Bad memory alignment in function '%s' in file '%s' on line %d!\n", __func__, __FILE__, __LINE__) +#define ASSERT_NULL(p) if ((p) == NULL) ERROR("NULL in function '%s' in file '%s' on line %d!\n", __func__, __FILE__, __LINE__) + #define ALIGN(p,t) (((size_t)(p) + (sizeof(t) - 1)) & ~(sizeof(t) - 1)) #endif //ETHERLIB_UTILS_H