LCOV - code coverage report
Current view: top level - libs/bsp/bspDynamicClient/include/io - DynamicClientCfg.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.0 % 25 22
Test Date: 2026-02-24 11:21:15 Functions: 100.0 % 3 3

            Line data    Source code
       1              : // Copyright 2024 Accenture.
       2              : 
       3              : #pragma once
       4              : 
       5              : #include "platform/estdint.h"
       6              : 
       7              : /**
       8              :  * This data type provides an abstract runtime mapping between a common shared I/O and
       9              :  * higher-level instances that can use this I/O.
      10              :  *
      11              :  * Usage: create an instance of dynamic client inside the class responsible for distribution of the
      12              :  * I/O channels that have to be dynamic, and provide public methods for adding and removing the
      13              :  * dynamic client.
      14              :  *
      15              :  * @tparam T - type that contains client's index + index of a channel inside a client.
      16              :  * @tparam IDynamicClient - type of an object that should be registered as a dynamic client
      17              :  * @tparam Size - bit width for count of clients, number of clients then is 2^Size
      18              :  * @tparam dynamicChannelsCount - number of dynamic channels that can be stored in this structure
      19              :  * @tparam dynamicClientsCount - number of dynamic clients that use this proxy.
      20              :  */
      21              : template<
      22              :     typename T,
      23              :     typename IDynamicClient,
      24              :     int32_t Size,
      25              :     int32_t dynamicChannelsCount,
      26              :     int32_t dynamicClientsCount = 0>
      27              : struct dynamicClient
      28              : {
      29              :     //[Enum_start]
      30              : 
      31              :     enum
      32              :     {
      33              :         bitWidthDynamicClientCount         = Size,
      34              :         bitWidthDynamicClientsChannelCount = ((sizeof(T) * 8) - bitWidthDynamicClientCount),
      35              :         maxDynamicClientCount              = (0x01U << bitWidthDynamicClientCount),
      36              :         channelInvalid                     = (0x01U << bitWidthDynamicClientsChannelCount) - 1U,
      37              :         dynamicClientInvalid               = (0x01U << bitWidthDynamicClientCount) - 1U,
      38              :         dynamicChannels                    = dynamicChannelsCount
      39              :     };
      40              : 
      41              :     //[Enum_end]
      42              : 
      43              :     /**
      44              :      * If dynamicClientsCount is not explicitly specified, maximum possible dynamicClientsCount is
      45              :      * selected.
      46              :      */
      47              :     static T const dynamicClientCountCfg
      48              :         = (dynamicClientsCount == 0 ? static_cast<int32_t>(maxDynamicClientCount)
      49              :                                     : dynamicClientsCount);
      50              : 
      51              :     /**
      52              :      * This structure is responsible for distributing number of clients and number of
      53              :      * instances per client.
      54              :      * If T is 8 bit, then dynamicClient can devote N bits to instances' indexing and (8-N) bits to
      55              :      * indexing inside a single client.
      56              :      * Example:
      57              :      * T = uint8_t, Size = 2 --> instanceNumber is in [0..3], numberInsideClient is in [0..31]
      58              :      */
      59              :     using tDynamicClientCfg = struct
      60              :     {
      61              :         T numberInsideClient : bitWidthDynamicClientsChannelCount;
      62              :         T instanceNumber : bitWidthDynamicClientCount;
      63              :     };
      64              : 
      65              :     // METHOD_START
      66              :     /**
      67              :      * Clean all Clients
      68              :      */
      69              :     static void cleanDynamicClients();
      70              : 
      71              :     /**
      72              :      * Check Valid Channel
      73              :      * @param : number of channel
      74              :      * @ret   : true is valid ,false - not valid
      75              :      */
      76              :     static bool getClientValid(T channel);
      77              : 
      78              :     /**
      79              :      * setDynamicClient
      80              :      * @param : channel number ,
      81              :      * @param : numberInsideClient , channel number inside the Client
      82              :      * @param : IDynamicClient* client
      83              :      * @ret   : true , false
      84              :      */
      85              :     bool setDynamicClient(T channel, T numberInsideClient, IDynamicClient* client);
      86              : 
      87              :     /**
      88              :      * clearDynamicClient
      89              :      * @param : channel number ,
      90              :      * @ret   : true , false
      91              :      */
      92              :     bool clearDynamicClient(T channel);
      93              : 
      94              :     /**
      95              :      * getClientInstance, channel has to be first checked using `getClientValid()` method
      96              :      * @param : number of channel
      97              :      * @ret   : IDynamicClient*
      98              :      */
      99            3 :     static inline IDynamicClient* getClientInstance(T channel)
     100              :     {
     101            3 :         return (fpDynamicClient[fDynamicChannelCfg[channel].instanceNumber]);
     102              :     }
     103              : 
     104            3 :     static inline T getChannelInsideClient(T channel)
     105              :     {
     106            3 :         return (fDynamicChannelCfg[channel].numberInsideClient);
     107              :     }
     108              : 
     109              :     static tDynamicClientCfg fDynamicChannelCfg[dynamicChannels];
     110              :     static IDynamicClient* fpDynamicClient[dynamicClientCountCfg];
     111              : 
     112              :     // METHOD_END
     113              : };
     114              : 
     115              : template<
     116              :     typename T,
     117              :     typename IDynamicClient,
     118              :     int32_t Size,
     119              :     int32_t dynamicChannelsCount,
     120              :     int32_t dynamicClientCount>
     121              : typename dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     122              :     tDynamicClientCfg
     123              :         dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     124              :             fDynamicChannelCfg[dynamicChannels];
     125              : 
     126              : template<
     127              :     typename T,
     128              :     typename IDynamicClient,
     129              :     int32_t Size,
     130              :     int32_t dynamicChannels,
     131              :     int32_t dynamicClientCount>
     132              : IDynamicClient* dynamicClient<T, IDynamicClient, Size, dynamicChannels, dynamicClientCount>::
     133              :     fpDynamicClient[dynamicClientCountCfg];
     134              : 
     135              : template<
     136              :     typename T,
     137              :     typename IDynamicClient,
     138              :     int32_t Size,
     139              :     int32_t dynamicChannelsCount,
     140              :     int32_t dynamicClientCount>
     141              : void dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     142              :     cleanDynamicClients()
     143              : {
     144              :     for (int32_t i = 0; i < (dynamicClientCountCfg); i++)
     145              :     {
     146              :         fpDynamicClient[i] = nullptr;
     147              :     }
     148              :     for (int32_t i = 0; i < (dynamicChannels); i++)
     149              :     {
     150              :         fDynamicChannelCfg[i].numberInsideClient = channelInvalid;
     151              :         fDynamicChannelCfg[i].instanceNumber     = dynamicClientInvalid;
     152              :     }
     153              : }
     154              : 
     155              : template<
     156              :     typename T,
     157              :     typename IDynamicClient,
     158              :     int32_t Size,
     159              :     int32_t dynamicChannelsCount,
     160              :     int32_t dynamicClientCount>
     161              : bool dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     162              :     getClientValid(T channel)
     163              : {
     164              :     bool ret = false;
     165              :     if (channel < dynamicChannels)
     166              :     {
     167              :         T instanceNumber = fDynamicChannelCfg[channel].instanceNumber;
     168              :         if (instanceNumber < dynamicClientCountCfg)
     169              :         {
     170              :             if ((instanceNumber < dynamicClientInvalid)
     171              :                 && (fDynamicChannelCfg[channel].numberInsideClient < channelInvalid)
     172              :                 && (fpDynamicClient[instanceNumber] != nullptr))
     173              :             {
     174              :                 ret = true;
     175              :             }
     176              :         }
     177              :     }
     178              : 
     179              :     return ret;
     180              : }
     181              : 
     182              : template<
     183              :     typename T,
     184              :     typename IDynamicClient,
     185              :     int32_t Size,
     186              :     int32_t dynamicChannelsCount,
     187              :     int32_t dynamicClientCount>
     188            3 : bool dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     189              :     setDynamicClient(T channel, T numberInsideClient, IDynamicClient* client)
     190              : {
     191              :     // range of outputNumber check
     192            3 :     if (numberInsideClient >= channelInvalid)
     193              :     {
     194            0 :         return false;
     195              :     }
     196              : 
     197            3 :     if (channel < dynamicChannels) // number is out of range
     198              :     {
     199            3 :         uint8_t mySlot          = 0xFFU;
     200            3 :         uint8_t availableClient = 0xFFU;
     201           20 :         for (T i = 0; (i < dynamicClientCountCfg) && (availableClient == 0xFFU); i++)
     202              :         {
     203           17 :             if (client == fpDynamicClient[i])
     204              :             {
     205            1 :                 availableClient = static_cast<uint8_t>(i);
     206              :             }
     207           17 :             if (fpDynamicClient[i] == nullptr)
     208              :             {
     209           15 :                 if (mySlot == 0xFFU)
     210              :                 {
     211            2 :                     mySlot = static_cast<uint8_t>(i);
     212              :                 }
     213              :             }
     214              :         }
     215              :         // Occupy slot for client
     216            3 :         if (availableClient == 0xFFU) // not in Map yet
     217              :         {
     218            2 :             if (mySlot != 0xFFU) // placed
     219              :             {
     220            2 :                 fpDynamicClient[mySlot] = client;
     221              :             }
     222              :             else // no free place
     223              :             {
     224            0 :                 return false;
     225              :             }
     226              :         }
     227              :         else
     228              :         {
     229            1 :             mySlot = availableClient;
     230              :         }
     231              : 
     232            3 :         fDynamicChannelCfg[channel].numberInsideClient = numberInsideClient;
     233            3 :         fDynamicChannelCfg[channel].instanceNumber     = mySlot;
     234            3 :         return true;
     235              :     }
     236              :     else
     237              :     {
     238            0 :         return false;
     239              :     }
     240              : }
     241              : 
     242              : template<
     243              :     typename T,
     244              :     typename IDynamicClient,
     245              :     int32_t Size,
     246              :     int32_t dynamicChannelsCount,
     247              :     int32_t dynamicClientCount>
     248              : bool dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     249              :     clearDynamicClient(T channel)
     250              : {
     251              :     if (channel < dynamicChannels) // number is out of range
     252              :     {
     253              :         T instanceNumber       = fDynamicChannelCfg[channel].instanceNumber;
     254              :         IDynamicClient* client = fpDynamicClient[instanceNumber];
     255              : 
     256              :         fDynamicChannelCfg[channel].numberInsideClient = channelInvalid;
     257              :         fDynamicChannelCfg[channel].instanceNumber     = dynamicClientInvalid;
     258              :         // look for other outputs
     259              : 
     260              :         if ((client == nullptr) || (instanceNumber >= dynamicClientCountCfg))
     261              :         {
     262              :             return true;
     263              :         }
     264              : 
     265              :         uint8_t availableClient = 0xFFU;
     266              :         for (T i = 0; i < dynamicClientCountCfg; i++)
     267              :         {
     268              :             if (client == fpDynamicClient[i])
     269              :             {
     270              :                 availableClient = i; // Found a client
     271              :                 break;
     272              :             }
     273              :         }
     274              :         if (availableClient != 0xFFU)
     275              :         {
     276              :             bool found = false;
     277              :             for (T i = 0; i < dynamicChannels; i++)
     278              :             {
     279              :                 if (fDynamicChannelCfg[i].instanceNumber == availableClient)
     280              :                 {
     281              :                     found = true;
     282              :                     break;
     283              :                 }
     284              :             }
     285              :             if (!found)
     286              :             {
     287              :                 // No client was found, the link can be deleted.
     288              :                 fpDynamicClient[availableClient] = nullptr;
     289              :             }
     290              :         }
     291              : 
     292              :         return true;
     293              :     }
     294              :     else
     295              :     {
     296              :         return false;
     297              :     }
     298              : }
        

Generated by: LCOV version 2.0-1