Adds NR CDRX config for cmx500 controller

Bug: 282827341
Bug: 291612493
Test: manually run with locally updated acts_tests.zip file
Change-Id: Ie710856dc5e308b94399a493889f495019426fe0
diff --git a/acts/framework/acts/controllers/cellular_lib/LteCellConfig.py b/acts/framework/acts/controllers/cellular_lib/LteCellConfig.py
index 8af943f..be7782b 100644
--- a/acts/framework/acts/controllers/cellular_lib/LteCellConfig.py
+++ b/acts/framework/acts/controllers/cellular_lib/LteCellConfig.py
@@ -114,6 +114,7 @@
         self.drx_retransmission_timer = None
         self.drx_long_cycle = None
         self.drx_long_cycle_offset = None
+        self.tracking_area = None
         self.disable_all_ul_subframes = None
 
     def __str__(self):
@@ -387,8 +388,6 @@
 
         if self.PARAM_TA in parameters:
             self.tracking_area = int(parameters[self.PARAM_TA])
-        else:
-            self.tracking_area = None
 
     def get_duplex_mode(self):
         """ Determines if the cell uses FDD or TDD duplex mode
diff --git a/acts/framework/acts/controllers/cellular_lib/NrCellConfig.py b/acts/framework/acts/controllers/cellular_lib/NrCellConfig.py
index a38f1c6..01f6125 100644
--- a/acts/framework/acts/controllers/cellular_lib/NrCellConfig.py
+++ b/acts/framework/acts/controllers/cellular_lib/NrCellConfig.py
@@ -40,6 +40,7 @@
     PARAM_UL_RBS = "ul_rbs"
     PARAM_TA = "tracking_area"
     PARAM_DRX = "drx"
+
     PARAM_DISABLE_ALL_UL_SLOTS = "disable_all_ul_slots"
     PARAM_CONFIG_FLEXIBLE_SLOTS = "config_flexible_slots"
 
@@ -62,6 +63,15 @@
         self.drx_connected_mode = None
         self.disable_all_ul_slots = None
         self.config_flexible_slots = None
+        self.drx_on_duration_timer = None
+        self.drx_inactivity_timer = None
+        self.drx_retransmission_timer_dl = None
+        self.drx_retransmission_timer_ul = None
+        self.drx_long_cycle = None
+        self.harq_rtt_timer_dl = 0
+        self.harq_rtt_timer_ul = 0
+        self.slot_offset = 0
+
 
     def configure(self, parameters):
         """ Configures an NR cell using a dictionary of parameters.
@@ -152,5 +162,61 @@
         self.config_flexible_slots = parameters.get(
             self.PARAM_CONFIG_FLEXIBLE_SLOTS, False)
 
+        if self.PARAM_DRX in parameters and len(
+                parameters[self.PARAM_DRX]) >= 6:
+            self.drx_connected_mode = True
+            param_drx = parameters[self.PARAM_DRX]
+            self.drx_on_duration_timer = param_drx[0]
+            self.drx_inactivity_timer = param_drx[1]
+            self.drx_retransmission_timer_dl = param_drx[2]
+            self.drx_retransmission_timer_ul = param_drx[3]
+            self.drx_long_cycle = param_drx[4]
+            try:
+                long_cycle = int(param_drx[4])
+                long_cycle_offset = int(param_drx[5])
+                if long_cycle_offset in range(0, long_cycle):
+                    self.drx_long_cycle_offset = long_cycle_offset
+                else:
+                    self.log.error(
+                        ("The cDRX long cycle offset must be in the "
+                         "range 0 to (long cycle  - 1). Setting "
+                         "long cycle offset to 0"))
+                    self.drx_long_cycle_offset = 0
+
+                self.harq_rtt_timer_dl = (
+                    int(param_drx[6])
+                    if len(param_drx) >= 7
+                    else 0
+                )
+                self.harq_rtt_timer_ul = (
+                    int(param_drx[7])
+                    if len(param_drx) >= 8
+                    else 0
+                )
+                self.slot_offset = (
+                    int(param_drx[8])
+                    if len(param_drx) >= 9
+                    else 0
+                )
+
+            except ValueError:
+                self.log.error(("cDRX long cycle and long cycle offset "
+                                "must be integers. Disabling cDRX mode."))
+                self.drx_connected_mode = False
+        else:
+            self.log.warning(
+                 "DRX mode was not configured properly.\n"
+                 "Please provide a list with the following values:\n"
+                 "1) DRX on duration timer\n"
+                 "2) Inactivity timer\n"
+                 "3) Retransmission timer dl\n"
+                 "4) Retransmission timer ul\n"
+                 "5) Long DRX cycle duration\n"
+                 "6) Long DRX cycle offset\n"
+                 "7) harq RTT timer dl\n"
+                 "8) harq RTT timer ul\n"
+                 "9) slot offset\n"
+                 "Example: [2, 6, 1, 1, 160, 0, 0, 0, 0].")
+
     def __str__(self):
         return str(vars(self))
diff --git a/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py b/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py
index cfa8079..0d3a9a3 100644
--- a/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py
+++ b/acts/framework/acts/controllers/rohdeschwarz_lib/cmx500.py
@@ -1397,7 +1397,75 @@
 
         config: The NrCellConfig for current base station.
         """
-        logger.warning('Not implement yet')
+        logger.info(
+            f'Configure Nr drx with\n'
+            f'drx_on_duration_timer: {config.drx_on_duration_timer}\n'
+            f'drx_inactivity_timer: {config.drx_inactivity_timer}\n'
+            f'drx_retransmission_timer_dl: {config.drx_retransmission_timer_dl}\n'
+            f'drx_retransmission_timer_ul: {config.drx_retransmission_timer_ul}\n'
+            f'drx_long_cycle: {config.drx_long_cycle}\n'
+            f'drx_long_cycle_offset: {config.drx_long_cycle_offset}\n'
+            f'harq_rtt_timer_dl: {config.harq_rtt_timer_dl}\n'
+            f'harq_rtt_timer_ul: {config.harq_rtt_timer_ul}\n'
+            f'slot_offset: {config.slot_offset}\n'
+        )
+
+        from mrtype.nr.drx import (
+            NrDrxConfig,
+            NrDrxInactivityTimer,
+            NrDrxOnDurationTimer,
+            NrDrxRetransmissionTimer,
+            NrDrxHarqRttTimer,
+            NrDrxSlotOffset,
+        )
+
+        from mrtype.nr.drx import NrDrxLongCycleStartOffset as longCycle
+
+        long_cycle_mapping = {
+            10: longCycle.ms10, 20: longCycle.ms20, 32: longCycle.ms32,
+            40: longCycle.ms40, 60: longCycle.ms60, 64: longCycle.ms64,
+            70: longCycle.ms70, 80: longCycle.ms80, 128: longCycle.ms128,
+            160: longCycle.ms160, 256: longCycle.ms256, 320: longCycle.ms320,
+            512: longCycle.ms512, 640: longCycle.ms640, 1024: longCycle.ms1024,
+            1280: longCycle.ms1280, 2048: longCycle.ms2048,
+            2560: longCycle.ms2560,
+        }
+
+        drx_on_duration_timer = NrDrxOnDurationTimer(
+            int(config.drx_on_duration_timer)
+        )
+        drx_inactivity_timer = NrDrxInactivityTimer(
+            int(config.drx_inactivity_timer)
+        )
+        drx_retransmission_timer_dl = NrDrxRetransmissionTimer(
+            int(config.drx_retransmission_timer_dl)
+        )
+        drx_retransmission_timer_ul = NrDrxRetransmissionTimer(
+            int(config.drx_retransmission_timer_ul)
+        )
+        drx_long_cycle = long_cycle_mapping[int(config.drx_long_cycle)]
+        drx_long_cycle_offset = drx_long_cycle(
+            int(config.drx_long_cycle_offset)
+        )
+        harq_rtt_timer_dl = NrDrxHarqRttTimer(config.harq_rtt_timer_dl)
+        harq_rtt_timer_ul = NrDrxHarqRttTimer(config.harq_rtt_timer_ul)
+        slot_offset=NrDrxSlotOffset(config.slot_offset)
+
+        nr_drx_config = NrDrxConfig(
+            on_duration_timer=drx_on_duration_timer,
+            inactivity_timer=drx_inactivity_timer,
+            retransmission_timer_dl=drx_retransmission_timer_dl,
+            retransmission_timer_ul=drx_retransmission_timer_ul,
+            long_cycle_start_offset=drx_long_cycle_offset,
+            harq_rtt_timer_dl=harq_rtt_timer_dl,
+            harq_rtt_timer_ul=harq_rtt_timer_ul,
+            slot_offset=slot_offset,
+        )
+
+        self._cmx.dut.nr_cell_group().set_drx_and_adjust_scheduler(
+            nr_drx_config
+        )
+        self._network.apply_changes()
 
     def set_dl_channel(self, channel):
         """Sets the downlink channel number of cell.
diff --git a/acts_tests/tests/google/power/tel/PowerTelPdcch_Modem_Test.py b/acts_tests/tests/google/power/tel/PowerTelPdcch_Modem_Test.py
index d2623b9..805dd65 100644
--- a/acts_tests/tests/google/power/tel/PowerTelPdcch_Modem_Test.py
+++ b/acts_tests/tests/google/power/tel/PowerTelPdcch_Modem_Test.py
@@ -54,3 +54,11 @@
     def test_nr_1_n78_pdcch(self):
         self.display_name_test_case = 'PDCCH 5G Sub6 NSA'
         self.power_pdcch_test()
+
+    def test_nr_1_n48_cdrx(self):
+        self.display_name_test_case = 'CDRx 5G Sub6 NSA'
+        self.power_pdcch_test()
+
+    def test_nr_1_n78_cdrx(self):
+        self.display_name_test_case = 'CDRx 5G Sub6 NSA'
+        self.power_pdcch_test()