LCOV - code coverage report
Current view: top level - home/jenkins/libs/bsp/bspDynamicClient/include/io - DynamicClientCfg.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 19 19 100.0 %
Date: 2025-06-27 13:41:45 Functions: 1 1 100.0 %

          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             :         return false;
     195             :     }
     196             : 
     197           3 :     if (channel < dynamicChannels) // number is out of range
     198             :     {
     199             :         uint8_t mySlot          = 0xFFU;
     200             :         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             :                 return false;
     225             :             }
     226             :         }
     227             :         else
     228             :         {
     229             :             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             :         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 1.14