/*****************************************************************************
* Copyright (c) 1990-2000 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/


// CircuitsConfig.cpp: 
//
//////////////////////////////////////////////////////////////////////

// Circuits Configuration bits (timeslot bundles)

BOOL SCircuitsConfig::Get(HKEY const hKey)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(hKey != NULL);
      HKEY hCircuit = NULL;
      HKEY hCSU = NULL;
      CString Key;
      int Circuit = 0;

      Key.Format(DXB_REGKEY_DS1);
      AffirmThrow(RegCreateKey(hKey, Key, &hCSU));
      AffirmThrow(hCSU != NULL);

      try
      {
         // The first circuit is defaulted to full line usage, single circuit protocols use this...
         Key.Format("%d",Circuit);
         AffirmThrow(RegCreateKey(hCSU, Key, &hCircuit));
         AffirmThrow(hCircuit != NULL);
         AffirmThrow(RegReadDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_TS_MASK, &TimeSlotMask[Circuit], DXB_REGVAL_CSU_FRACT1_TS_MASK_DEFAULT));
         AffirmThrow(RegReadDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_SPD_MASK, &SpeedMask[Circuit], DXB_REGVAL_CSU_FRACT1_SPD_MASK_DEFAULT));
         RegCloseKey(hCircuit);
         // TRACE("Circuit:%d:TimeSlotMask:0x%x, SpeedMask:0x%x\n", Circuit, TimeSlotMask[Circuit], SpeedMask[Circuit]);

         // Subsequent circuits are by default unused
         for (Circuit = 1; Circuit < MAX_T1_CIRCUITS; Circuit++)
         {
            Key.Format("%d",Circuit);
            AffirmThrow(RegCreateKey(hCSU, Key, &hCircuit));
            AffirmThrow(hCircuit != NULL);
            AffirmThrow(RegReadDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_TS_MASK, &TimeSlotMask[Circuit], 0));
            AffirmThrow(RegReadDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_SPD_MASK, &SpeedMask[Circuit], DXB_REGVAL_CSU_FRACT1_SPD_MASK_DEFAULT));
            // TRACE("Circuit:%d:TimeSlotMask:0x%x, SpeedMask:0x%x\n", Circuit, TimeSlotMask[Circuit], SpeedMask[Circuit]);
            RegCloseKey(hCircuit);
            hCircuit = NULL;
         }

         // Redundant, used to check consistency
         {
            DWORD Mask, Count;
            AffirmThrow(RegReadDWordValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_MASK, &Mask, DXB_REGVAL_CSU_FRACT1_CKT_MASK_DEFAULT));
            AffirmThrow(RegReadDWordValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_COUNT, &Count, DXB_REGVAL_CSU_FRACT1_CKT_COUNT_DEFAULT));
            // Sanity check...
            UpdateCounts();
            AffirmThrow((Mask==CircuitMask) && (Count==CircuitCount));
         }

         fSuccess = TRUE;
      }
      catch (CAffirmException ae)
      {
         if (NULL != hCircuit)
            RegCloseKey(hCircuit);
      }

      RegCloseKey(hCSU);
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL SCircuitsConfig::Set(HKEY const hKey)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(hKey != NULL);
      HKEY hCircuit = NULL;
      HKEY hCSU = NULL;
      CString Key;
      int Circuit = 0;

      UpdateCounts();

      Key.Format(DXB_REGKEY_DS1);
      AffirmThrow(RegCreateKey(hKey, Key, &hCSU));
      AffirmThrow(hCSU != NULL);

      try
      {
         AffirmThrow(RegWriteDWordValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_MASK, CircuitMask));
         AffirmThrow(RegWriteDWordValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_COUNT, CircuitCount));

         for (Circuit = 0; Circuit < MAX_T1_CIRCUITS; Circuit++)
         {
            Key.Format("%d",Circuit);
            AffirmThrow(RegCreateKey(hCSU, Key, &hCircuit));
            AffirmThrow(hCircuit != NULL);
            AffirmThrow(RegWriteDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_TS_MASK, TimeSlotMask[Circuit]));
            AffirmThrow(RegWriteDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_SPD_MASK, SpeedMask[Circuit]));
            RegCloseKey(hCircuit);
            hCircuit = NULL;
         }
         fSuccess = TRUE;
      }
      catch (CAffirmException ae)
      {
         if (NULL != hCircuit)
            RegCloseKey(hCircuit);
      }

      RegCloseKey(hCSU);
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL SCircuitsConfig::SetOnly(HKEY const hKey)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(hKey != NULL);
      HKEY hCircuit = NULL;
      HKEY hCSU = NULL;
      CString Key;
      int Circuit = 0;

      UpdateCounts();

      Key.Format(DXB_REGKEY_DS1);
      AffirmThrow(RegCreateKey(hKey, Key, &hCSU));
      AffirmThrow(hCSU != NULL);

      try
      {
         AffirmThrow(RegWriteDWordValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_MASK, CircuitMask));
         AffirmThrow(RegWriteDWordValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_COUNT, CircuitCount));

         for (Circuit = 0; Circuit < MAX_T1_CIRCUITS; Circuit++)
         {
            Key.Format("%d",Circuit);

            // Only write the timeslot masks that are configured, delete the rest
            if (0 == TimeSlotMask[Circuit])
            {
               AffirmThrow(RegDelKey(hCSU, Key));
            }
            else
            {
               AffirmThrow(RegCreateKey(hCSU, Key, &hCircuit));
               AffirmThrow(hCircuit != NULL);
               AffirmThrow(RegWriteDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_TS_MASK, TimeSlotMask[Circuit]));
               AffirmThrow(RegWriteDWordValue(hCircuit, DXB_REGVAL_CSU_FRACT1_SPD_MASK, SpeedMask[Circuit]));
               RegCloseKey(hCircuit);
               hCircuit = NULL;
            }
         }
         fSuccess = TRUE;
      }
      catch (CAffirmException ae)
      {
         if (NULL != hCircuit)
            RegCloseKey(hCircuit);
      }

      RegCloseKey(hCSU);
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL SCircuitsConfig::Remove(HKEY const hKey)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(hKey != NULL);
      HKEY hCircuit = NULL;
      HKEY hCSU = NULL;
      CString Key;
      int Circuit = 0;

      Key.Format(DXB_REGKEY_DS1);
      AffirmThrow(RegCreateKey(hKey, Key, &hCSU));
      AffirmThrow(hCSU != NULL);

      try
      {
         AffirmThrow(RegDelValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_MASK));
         AffirmThrow(RegDelValue(hCSU, DXB_REGVAL_CSU_FRACT1_CKT_COUNT));

         for (Circuit = 0; Circuit < MAX_T1_CIRCUITS; Circuit++)
         {
            Key.Format("%d",Circuit);
            AffirmThrow(RegCreateKey(hCSU, Key, &hCircuit));
            AffirmThrow(hCircuit != NULL);
            AffirmThrow(RegDelValue(hCircuit, DXB_REGVAL_CSU_FRACT1_TS_MASK));
            AffirmThrow(RegDelValue(hCircuit, DXB_REGVAL_CSU_FRACT1_SPD_MASK));
            RegCloseKey(hCircuit);
            hCircuit = NULL;
         }
         fSuccess = TRUE;
      }
      catch (CAffirmException ae)
      {
         if (NULL != hCircuit)
            RegCloseKey(hCircuit);
      }

      RegCloseKey(hCSU);
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

void SCircuitsConfig::MakeSingleCircuit(DWORD const nTimeSlotMask, DWORD const nSpeedMask)
{
   // Fill in the first circuit's values...
   TimeSlotMask[0] = nTimeSlotMask;
   SpeedMask[0] = nSpeedMask;
   // ... clear out the rest
   for (int Circuit = 1; Circuit < MAX_T1_CIRCUITS; Circuit++)
   {
      TimeSlotMask[Circuit] = 0;
      SpeedMask[Circuit] = 0;
   }
   UpdateCounts();
}

void SCircuitsConfig::UpdateCounts(void)
{
   DWORD Count = 0;
   DWORD Mask = 0;
   DWORD Bit = 0x00000001;

   for (int Circuit = 0; Circuit < MAX_T1_CIRCUITS; Circuit++, Bit <= 1)
   {
      if (0 != TimeSlotMask[Circuit])
      {
         Mask |= Bit;
         Count++;
      }
   }

   CircuitMask = Mask;
   CircuitCount = Count;
}

DWORD SCircuitsConfig::GetSingleCircuitMask(void)
{
   return TimeSlotMask[0];
}
