diff --git a/state_machines/enb_acs_states.py b/state_machines/enb_acs_states.py
new file mode 100644
index 0000000..a9b84a5
--- /dev/null
+++ b/state_machines/enb_acs_states.py
@@ -0,0 +1,1293 @@
+"""
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from abc import ABC, abstractmethod
+from collections import namedtuple
+from typing import Any, Optional
+
+from data_models.data_model import InvalidTrParamPath
+from data_models.data_model_parameters import ParameterName
+from device_config.configuration_init import build_desired_config
+from exceptions import ConfigurationError, Tr069Error
+from logger import EnodebdLogger as logger
+from state_machines.acs_state_utils import (
+    does_inform_have_event,
+    get_all_objects_to_add,
+    get_all_objects_to_delete,
+    get_all_param_values_to_set,
+    get_obj_param_values_to_set,
+    get_object_params_to_get,
+    get_optional_param_to_check,
+    get_param_values_to_set,
+    get_params_to_get,
+    parse_get_parameter_values_response,
+    process_inform_message,
+)
+from state_machines.enb_acs import EnodebAcsStateMachine
+from state_machines.timer import StateMachineTimer
+from tr069 import models
+
+AcsMsgAndTransition = namedtuple(
+    'AcsMsgAndTransition', ['msg', 'next_state'],
+)
+
+AcsReadMsgResult = namedtuple(
+    'AcsReadMsgResult', ['msg_handled', 'next_state'],
+)
+
+
+class EnodebAcsState(ABC):
+    """
+    State class for the Enodeb state machine
+
+    States can transition after reading a message from the eNB, sending a
+    message out to the eNB, or when a timer completes. As such, some states
+    are only responsible for message sending, and others are only responsible
+    for reading incoming messages.
+
+    In the constructor, set up state transitions.
+    """
+
+    def __init__(self):
+        self._acs = None
+
+    def enter(self) -> None:
+        """
+        Set up your timers here. Call transition(..) on the ACS when the timer
+        completes or throw an error
+        """
+        pass
+
+    def exit(self) -> None:
+        """Destroy timers here"""
+        pass
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        Args: message: tr069 message
+        Returns: name of the next state, if transition required
+        """
+        raise ConfigurationError(
+            '%s should implement read_msg() if it '
+            'needs to handle message reading' % self.__class__.__name__,
+        )
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        """
+        Produce a message to send back to the eNB.
+
+        Args:
+            message: TR-069 message which was already processed by read_msg
+
+        Returns: Message and possible transition
+        """
+        raise ConfigurationError(
+            '%s should implement get_msg() if it '
+            'needs to produce messages' % self.__class__.__name__,
+        )
+
+    @property
+    def acs(self) -> EnodebAcsStateMachine:
+        return self._acs
+
+    @acs.setter
+    def acs(self, val: EnodebAcsStateMachine) -> None:
+        self._acs = val
+
+    @abstractmethod
+    def state_description(self) -> str:
+        """ Provide a few words about what the state represents """
+        pass
+
+
+class WaitInformState(EnodebAcsState):
+    """
+    This state indicates that no Inform message has been received yet, or
+    that no Inform message has been received for a long time.
+
+    This state is used to handle an Inform message that arrived when enodebd
+    already believes that the eNB is connected. As such, it is unclear to
+    enodebd whether the eNB is just sending another Inform, or if a different
+    eNB was plugged into the same interface.
+    """
+
+    def __init__(
+        self,
+        acs: EnodebAcsStateMachine,
+        when_done: str,
+        when_boot: Optional[str] = None,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.boot_transition = when_boot
+        self.has_enb_just_booted = False
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        Args:
+            message: models.Inform Tr069 Inform message
+        """
+        if not isinstance(message, models.Inform):
+            return AcsReadMsgResult(False, None)
+        process_inform_message(
+            message, self.acs.data_model,
+            self.acs.device_cfg,
+        )
+        if does_inform_have_event(message, '1 BOOT'):
+            return AcsReadMsgResult(True, self.boot_transition)
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        """ Reply with InformResponse """
+        response = models.InformResponse()
+        # Set maxEnvelopes to 1, as per TR-069 spec
+        response.MaxEnvelopes = 1
+        return AcsMsgAndTransition(response, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Waiting for an Inform'
+
+
+class GetRPCMethodsState(EnodebAcsState):
+    """
+    After the first Inform message from boot, it is expected that the eNB
+    will try to learn the RPC methods of the ACS.
+    """
+
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str, when_skip: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.skip_transition = when_skip
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        # If this is a regular Inform, not after a reboot we'll get an empty
+        if isinstance(message, models.DummyInput):
+            return AcsReadMsgResult(True, self.skip_transition)
+        if not isinstance(message, models.GetRPCMethods):
+            return AcsReadMsgResult(False, self.done_transition)
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        resp = models.GetRPCMethodsResponse()
+        resp.MethodList = models.MethodList()
+        RPC_METHODS = ['Inform', 'GetRPCMethods', 'TransferComplete']
+        resp.MethodList.arrayType = 'xsd:string[%d]' \
+                                          % len(RPC_METHODS)
+        resp.MethodList.string = RPC_METHODS
+        return AcsMsgAndTransition(resp, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Waiting for incoming GetRPC Methods after boot'
+
+
+class BaicellsRemWaitState(EnodebAcsState):
+    """
+    We've already received an Inform message. This state is to handle a
+    Baicells eNodeB issue.
+
+    After eNodeB is rebooted, hold off configuring it for some time to give
+    time for REM to run. This is a BaiCells eNodeB issue that doesn't support
+    enabling the eNodeB during initial REM.
+
+    In this state, just hang at responding to Inform, and then ending the
+    TR-069 session.
+    """
+
+    CONFIG_DELAY_AFTER_BOOT = 600
+
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.rem_timer = None
+
+    def enter(self):
+        self.rem_timer = StateMachineTimer(self.CONFIG_DELAY_AFTER_BOOT)
+        logger.info(
+            'Holding off of eNB configuration for %s seconds. '
+            'Will resume after eNB REM process has finished. ',
+            self.CONFIG_DELAY_AFTER_BOOT,
+        )
+
+    def exit(self):
+        self.rem_timer = None
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        if not isinstance(message, models.Inform):
+            return AcsReadMsgResult(False, None)
+        process_inform_message(
+            message, self.acs.data_model,
+            self.acs.device_cfg,
+        )
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        if self.rem_timer.is_done():
+            return AcsMsgAndTransition(
+                models.DummyInput(),
+                self.done_transition,
+            )
+        return AcsMsgAndTransition(models.DummyInput(), None)
+
+    def state_description(self) -> str:
+        remaining = self.rem_timer.seconds_remaining()
+        return 'Waiting for eNB REM to run for %d more seconds before ' \
+               'resuming with configuration.' % remaining
+
+
+class WaitEmptyMessageState(EnodebAcsState):
+    def __init__(
+        self,
+        acs: EnodebAcsStateMachine,
+        when_done: str,
+        when_missing: Optional[str] = None,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.unknown_param_transition = when_missing
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        It's expected that we transition into this state right after receiving
+        an Inform message and replying with an InformResponse. At that point,
+        the eNB sends an empty HTTP request (aka DummyInput) to initiate the
+        rest of the provisioning process
+        """
+        if not isinstance(message, models.DummyInput):
+            logger.debug("Ignoring message %s", str(type(message)))
+            return AcsReadMsgResult(msg_handled=False, next_state=None)
+        if self.unknown_param_transition:
+            if get_optional_param_to_check(self.acs.data_model):
+                return AcsReadMsgResult(
+                    msg_handled=True,
+                    next_state=self.unknown_param_transition,
+                )
+        return AcsReadMsgResult(
+            msg_handled=True,
+            next_state=self.done_transition,
+        )
+
+    def get_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        Return a dummy message waiting for the empty message from CPE
+        """
+        request = models.DummyInput()
+        return AcsMsgAndTransition(msg=request, next_state=None)
+
+    def state_description(self) -> str:
+        return 'Waiting for empty message from eNodeB'
+
+
+class CheckOptionalParamsState(EnodebAcsState):
+    def __init__(
+            self,
+            acs: EnodebAcsStateMachine,
+            when_done: str,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.optional_param = None
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        self.optional_param = get_optional_param_to_check(self.acs.data_model)
+        if self.optional_param is None:
+            raise Tr069Error('Invalid State')
+        # Generate the request
+        request = models.GetParameterValues()
+        request.ParameterNames = models.ParameterNames()
+        request.ParameterNames.arrayType = 'xsd:string[1]'
+        request.ParameterNames.string = []
+        path = self.acs.data_model.get_parameter(self.optional_param).path
+        request.ParameterNames.string.append(path)
+        return AcsMsgAndTransition(request, None)
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """ Process either GetParameterValuesResponse or a Fault """
+        if type(message) == models.Fault:
+            self.acs.data_model.set_parameter_presence(
+                self.optional_param,
+                False,
+            )
+        elif type(message) == models.GetParameterValuesResponse:
+            name_to_val = parse_get_parameter_values_response(
+                self.acs.data_model,
+                message,
+            )
+            logger.debug(
+                'Received CPE parameter values: %s',
+                str(name_to_val),
+            )
+            for name, val in name_to_val.items():
+                self.acs.data_model.set_parameter_presence(
+                    self.optional_param,
+                    True,
+                )
+                magma_val = self.acs.data_model.transform_for_magma(name, val)
+                self.acs.device_cfg.set_parameter(name, magma_val)
+        else:
+            return AcsReadMsgResult(False, None)
+
+        if get_optional_param_to_check(self.acs.data_model) is not None:
+            return AcsReadMsgResult(True, None)
+        return AcsReadMsgResult(True, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Checking if some optional parameters exist in data model'
+
+
+class SendGetTransientParametersState(EnodebAcsState):
+    """
+    Periodically read eNodeB status. Note: keep frequency low to avoid
+    backing up large numbers of read operations if enodebd is busy.
+    Some eNB parameters are read only and updated by the eNB itself.
+    """
+    PARAMETERS = [
+        ParameterName.OP_STATE,
+        ParameterName.RF_TX_STATUS,
+        ParameterName.GPS_STATUS,
+        ParameterName.PTP_STATUS,
+        ParameterName.MME_STATUS,
+        ParameterName.GPS_LAT,
+        ParameterName.GPS_LONG,
+    ]
+
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        if not isinstance(message, models.DummyInput):
+            return AcsReadMsgResult(False, None)
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        request = models.GetParameterValues()
+        request.ParameterNames = models.ParameterNames()
+        request.ParameterNames.string = []
+        for name in self.PARAMETERS:
+            # Not all data models have these parameters
+            if self.acs.data_model.is_parameter_present(name):
+                path = self.acs.data_model.get_parameter(name).path
+                request.ParameterNames.string.append(path)
+        request.ParameterNames.arrayType = \
+            'xsd:string[%d]' % len(request.ParameterNames.string)
+
+        return AcsMsgAndTransition(request, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Getting transient read-only parameters'
+
+
+class WaitGetTransientParametersState(EnodebAcsState):
+    """
+    Periodically read eNodeB status. Note: keep frequency low to avoid
+    backing up large numbers of read operations if enodebd is busy
+    """
+
+    def __init__(
+            self,
+            acs: EnodebAcsStateMachine,
+            when_get: str,
+            when_get_obj_params: str,
+            when_delete: str,
+            when_add: str,
+            when_set: str,
+            when_skip: str,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_get
+        self.get_obj_params_transition = when_get_obj_params
+        self.rm_obj_transition = when_delete
+        self.add_obj_transition = when_add
+        self.set_transition = when_set
+        self.skip_transition = when_skip
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        if not isinstance(message, models.GetParameterValuesResponse):
+            return AcsReadMsgResult(False, None)
+        # Current values of the fetched parameters
+        name_to_val = parse_get_parameter_values_response(
+            self.acs.data_model,
+            message,
+        )
+        logger.debug('Fetched Transient Params: %s', str(name_to_val))
+
+        # Update device configuration
+        for name in name_to_val:
+            magma_val = \
+                self.acs.data_model.transform_for_magma(
+                    name,
+                    name_to_val[name],
+                )
+            self.acs.device_cfg.set_parameter(name, magma_val)
+
+        return AcsReadMsgResult(True, self.get_next_state())
+
+    def get_next_state(self) -> str:
+        should_get_params = \
+            len(
+                get_params_to_get(
+                    self.acs.device_cfg,
+                    self.acs.data_model,
+                ),
+            ) > 0
+        if should_get_params:
+            return self.done_transition
+        should_get_obj_params = \
+            len(
+                get_object_params_to_get(
+                    self.acs.desired_cfg,
+                    self.acs.device_cfg,
+                    self.acs.data_model,
+                ),
+            ) > 0
+        if should_get_obj_params:
+            return self.get_obj_params_transition
+        elif len(
+            get_all_objects_to_delete(
+                self.acs.desired_cfg,
+                self.acs.device_cfg,
+            ),
+        ) > 0:
+            return self.rm_obj_transition
+        elif len(
+            get_all_objects_to_add(
+                self.acs.desired_cfg,
+                self.acs.device_cfg,
+            ),
+        ) > 0:
+            return self.add_obj_transition
+        return self.skip_transition
+
+    def state_description(self) -> str:
+        return 'Getting transient read-only parameters'
+
+
+class GetParametersState(EnodebAcsState):
+    """
+    Get the value of most parameters of the eNB that are defined in the data
+    model. Object parameters are excluded.
+    """
+
+    def __init__(
+        self,
+        acs: EnodebAcsStateMachine,
+        when_done: str,
+        request_all_params: bool = False,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        # Set to True if we want to request values of all parameters, even if
+        # the ACS state machine already has recorded values of them.
+        self.request_all_params = request_all_params
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        It's expected that we transition into this state right after receiving
+        an Inform message and replying with an InformResponse. At that point,
+        the eNB sends an empty HTTP request (aka DummyInput) to initiate the
+        rest of the provisioning process
+        """
+        if not isinstance(message, models.DummyInput):
+            return AcsReadMsgResult(False, None)
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        """
+        Respond with GetParameterValuesRequest
+
+        Get the values of all parameters defined in the data model.
+        Also check which addable objects are present, and what the values of
+        parameters for those objects are.
+        """
+
+        # Get the names of regular parameters
+        names = get_params_to_get(
+            self.acs.device_cfg, self.acs.data_model,
+            self.request_all_params,
+        )
+
+        # Generate the request
+        request = models.GetParameterValues()
+        request.ParameterNames = models.ParameterNames()
+        request.ParameterNames.arrayType = 'xsd:string[%d]' \
+                                           % len(names)
+        request.ParameterNames.string = []
+        for name in names:
+            path = self.acs.data_model.get_parameter(name).path
+            if path is not InvalidTrParamPath:
+                # Only get data elements backed by tr69 path
+                request.ParameterNames.string.append(path)
+
+        return AcsMsgAndTransition(request, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Getting non-object parameters'
+
+
+class WaitGetParametersState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """ Process GetParameterValuesResponse """
+        if not isinstance(message, models.GetParameterValuesResponse):
+            return AcsReadMsgResult(False, None)
+        name_to_val = parse_get_parameter_values_response(
+            self.acs.data_model,
+            message,
+        )
+        logger.debug('Received CPE parameter values: %s', str(name_to_val))
+        for name, val in name_to_val.items():
+            magma_val = self.acs.data_model.transform_for_magma(name, val)
+            self.acs.device_cfg.set_parameter(name, magma_val)
+        return AcsReadMsgResult(True, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Getting non-object parameters'
+
+
+class GetObjectParametersState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        """ Respond with GetParameterValuesRequest """
+        names = get_object_params_to_get(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+            self.acs.data_model,
+        )
+
+        # Generate the request
+        request = models.GetParameterValues()
+        request.ParameterNames = models.ParameterNames()
+        request.ParameterNames.arrayType = 'xsd:string[%d]' \
+                                           % len(names)
+        request.ParameterNames.string = []
+        for name in names:
+            path = self.acs.data_model.get_parameter(name).path
+            request.ParameterNames.string.append(path)
+
+        return AcsMsgAndTransition(request, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Getting object parameters'
+
+
+class WaitGetObjectParametersState(EnodebAcsState):
+    def __init__(
+        self,
+        acs: EnodebAcsStateMachine,
+        when_delete: str,
+        when_add: str,
+        when_set: str,
+        when_skip: str,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.rm_obj_transition = when_delete
+        self.add_obj_transition = when_add
+        self.set_params_transition = when_set
+        self.skip_transition = when_skip
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """ Process GetParameterValuesResponse """
+        if not isinstance(message, models.GetParameterValuesResponse):
+            return AcsReadMsgResult(False, None)
+
+        path_to_val = {}
+        if hasattr(message.ParameterList, 'ParameterValueStruct') and \
+                message.ParameterList.ParameterValueStruct is not None:
+            for param_value_struct in message.ParameterList.ParameterValueStruct:
+                path_to_val[param_value_struct.Name] = \
+                    param_value_struct.Value.Data
+        logger.debug('Received object parameters: %s', str(path_to_val))
+
+        # Number of PLMN objects reported can be incorrect. Let's count them
+        num_plmns = 0
+        obj_to_params = self.acs.data_model.get_numbered_param_names()
+        while True:
+            obj_name = ParameterName.PLMN_N % (num_plmns + 1)
+            if obj_name not in obj_to_params or len(obj_to_params[obj_name]) == 0:
+                logger.warning(
+                    "eNB has PLMN %s but not defined in model",
+                    obj_name,
+                )
+                break
+            param_name_list = obj_to_params[obj_name]
+            obj_path = self.acs.data_model.get_parameter(param_name_list[0]).path
+            if obj_path not in path_to_val:
+                break
+            if not self.acs.device_cfg.has_object(obj_name):
+                self.acs.device_cfg.add_object(obj_name)
+            num_plmns += 1
+            for name in param_name_list:
+                path = self.acs.data_model.get_parameter(name).path
+                value = path_to_val[path]
+                magma_val = \
+                    self.acs.data_model.transform_for_magma(name, value)
+                self.acs.device_cfg.set_parameter_for_object(
+                    name, magma_val,
+                    obj_name,
+                )
+        num_plmns_reported = \
+                int(self.acs.device_cfg.get_parameter(ParameterName.NUM_PLMNS))
+        if num_plmns != num_plmns_reported:
+            logger.warning(
+                "eNB reported %d PLMNs but found %d",
+                num_plmns_reported, num_plmns,
+            )
+            self.acs.device_cfg.set_parameter(
+                ParameterName.NUM_PLMNS,
+                num_plmns,
+            )
+
+        # Now we can have the desired state
+        if self.acs.desired_cfg is None:
+            self.acs.desired_cfg = build_desired_config(
+                self.acs.mconfig,
+                self.acs.service_config,
+                self.acs.device_cfg,
+                self.acs.data_model,
+                self.acs.config_postprocessor,
+            )
+
+        if len(
+            get_all_objects_to_delete(
+                self.acs.desired_cfg,
+                self.acs.device_cfg,
+            ),
+        ) > 0:
+            return AcsReadMsgResult(True, self.rm_obj_transition)
+        elif len(
+            get_all_objects_to_add(
+                self.acs.desired_cfg,
+                self.acs.device_cfg,
+            ),
+        ) > 0:
+            return AcsReadMsgResult(True, self.add_obj_transition)
+        elif len(
+            get_all_param_values_to_set(
+                self.acs.desired_cfg,
+                self.acs.device_cfg,
+                self.acs.data_model,
+            ),
+        ) > 0:
+            return AcsReadMsgResult(True, self.set_params_transition)
+        return AcsReadMsgResult(True, self.skip_transition)
+
+    def state_description(self) -> str:
+        return 'Getting object parameters'
+
+
+class DeleteObjectsState(EnodebAcsState):
+    def __init__(
+        self,
+        acs: EnodebAcsStateMachine,
+        when_add: str,
+        when_skip: str,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.deleted_param = None
+        self.add_obj_transition = when_add
+        self.skip_transition = when_skip
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        """
+        Send DeleteObject message to TR-069 and poll for response(s).
+        Input:
+            - Object name (string)
+        """
+        request = models.DeleteObject()
+        self.deleted_param = get_all_objects_to_delete(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+        )[0]
+        request.ObjectName = \
+            self.acs.data_model.get_parameter(self.deleted_param).path
+        return AcsMsgAndTransition(request, None)
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        Send DeleteObject message to TR-069 and poll for response(s).
+        Input:
+            - Object name (string)
+        """
+        if type(message) == models.DeleteObjectResponse:
+            if message.Status != 0:
+                raise Tr069Error(
+                    'Received DeleteObjectResponse with '
+                    'Status=%d' % message.Status,
+                )
+        elif type(message) == models.Fault:
+            raise Tr069Error(
+                'Received Fault in response to DeleteObject '
+                '(faultstring = %s)' % message.FaultString,
+            )
+        else:
+            return AcsReadMsgResult(False, None)
+
+        self.acs.device_cfg.delete_object(self.deleted_param)
+        obj_list_to_delete = get_all_objects_to_delete(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+        )
+        if len(obj_list_to_delete) > 0:
+            return AcsReadMsgResult(True, None)
+        if len(
+            get_all_objects_to_add(
+                self.acs.desired_cfg,
+                self.acs.device_cfg,
+            ),
+        ) == 0:
+            return AcsReadMsgResult(True, self.skip_transition)
+        return AcsReadMsgResult(True, self.add_obj_transition)
+
+    def state_description(self) -> str:
+        return 'Deleting objects'
+
+
+class AddObjectsState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.added_param = None
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        request = models.AddObject()
+        self.added_param = get_all_objects_to_add(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+        )[0]
+        desired_param = self.acs.data_model.get_parameter(self.added_param)
+        desired_path = desired_param.path
+        path_parts = desired_path.split('.')
+        # If adding enumerated object, ie. XX.N. we should add it to the
+        # parent object XX. so strip the index
+        if len(path_parts) > 2 and \
+                path_parts[-1] == '' and path_parts[-2].isnumeric():
+            logger.debug('Stripping index from path=%s', desired_path)
+            desired_path = '.'.join(path_parts[:-2]) + '.'
+        request.ObjectName = desired_path
+        return AcsMsgAndTransition(request, None)
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        if type(message) == models.AddObjectResponse:
+            if message.Status != 0:
+                raise Tr069Error(
+                    'Received AddObjectResponse with '
+                    'Status=%d' % message.Status,
+                )
+        elif type(message) == models.Fault:
+            raise Tr069Error(
+                'Received Fault in response to AddObject '
+                '(faultstring = %s)' % message.FaultString,
+            )
+        else:
+            return AcsReadMsgResult(False, None)
+        instance_n = message.InstanceNumber
+        self.acs.device_cfg.add_object(self.added_param % instance_n)
+        obj_list_to_add = get_all_objects_to_add(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+        )
+        if len(obj_list_to_add) > 0:
+            return AcsReadMsgResult(True, None)
+        return AcsReadMsgResult(True, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Adding objects'
+
+
+class SetParameterValuesState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        request = models.SetParameterValues()
+        request.ParameterList = models.ParameterValueList()
+        param_values = get_all_param_values_to_set(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+            self.acs.data_model,
+        )
+        request.ParameterList.arrayType = 'cwmp:ParameterValueStruct[%d]' \
+                                           % len(param_values)
+        request.ParameterList.ParameterValueStruct = []
+        logger.debug(
+            'Sending TR069 request to set CPE parameter values: %s',
+            str(param_values),
+        )
+        # TODO: Match key response when we support having multiple outstanding
+        # calls.
+        if self.acs.has_version_key:
+            request.ParameterKey = models.ParameterKeyType()
+            request.ParameterKey.Data =\
+                "SetParameter-{:10.0f}".format(self.acs.parameter_version_key)
+            request.ParameterKey.type = 'xsd:string'
+
+        for name, value in param_values.items():
+            param_info = self.acs.data_model.get_parameter(name)
+            type_ = param_info.type
+            name_value = models.ParameterValueStruct()
+            name_value.Value = models.anySimpleType()
+            name_value.Name = param_info.path
+            enb_value = self.acs.data_model.transform_for_enb(name, value)
+            if type_ in ('int', 'unsignedInt'):
+                name_value.Value.type = 'xsd:%s' % type_
+                name_value.Value.Data = str(enb_value)
+            elif type_ == 'boolean':
+                # Boolean values have integral representations in spec
+                name_value.Value.type = 'xsd:boolean'
+                name_value.Value.Data = str(int(enb_value))
+            elif type_ == 'string':
+                name_value.Value.type = 'xsd:string'
+                name_value.Value.Data = str(enb_value)
+            else:
+                raise Tr069Error(
+                    'Unsupported type for %s: %s' %
+                    (name, type_),
+                )
+            if param_info.is_invasive:
+                self.acs.are_invasive_changes_applied = False
+            request.ParameterList.ParameterValueStruct.append(name_value)
+
+        return AcsMsgAndTransition(request, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Setting parameter values'
+
+
+class SetParameterValuesNotAdminState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        request = models.SetParameterValues()
+        request.ParameterList = models.ParameterValueList()
+        param_values = get_all_param_values_to_set(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+            self.acs.data_model,
+            exclude_admin=True,
+        )
+        request.ParameterList.arrayType = 'cwmp:ParameterValueStruct[%d]' \
+                                          % len(param_values)
+        request.ParameterList.ParameterValueStruct = []
+        logger.debug(
+            'Sending TR069 request to set CPE parameter values: %s',
+            str(param_values),
+        )
+        for name, value in param_values.items():
+            param_info = self.acs.data_model.get_parameter(name)
+            type_ = param_info.type
+            name_value = models.ParameterValueStruct()
+            name_value.Value = models.anySimpleType()
+            name_value.Name = param_info.path
+            enb_value = self.acs.data_model.transform_for_enb(name, value)
+            if type_ in ('int', 'unsignedInt'):
+                name_value.Value.type = 'xsd:%s' % type_
+                name_value.Value.Data = str(enb_value)
+            elif type_ == 'boolean':
+                # Boolean values have integral representations in spec
+                name_value.Value.type = 'xsd:boolean'
+                name_value.Value.Data = str(int(enb_value))
+            elif type_ == 'string':
+                name_value.Value.type = 'xsd:string'
+                name_value.Value.Data = str(enb_value)
+            else:
+                raise Tr069Error(
+                    'Unsupported type for %s: %s' %
+                    (name, type_),
+                )
+            if param_info.is_invasive:
+                self.acs.are_invasive_changes_applied = False
+            request.ParameterList.ParameterValueStruct.append(name_value)
+
+        return AcsMsgAndTransition(request, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Setting parameter values excluding Admin Enable'
+
+
+class WaitSetParameterValuesState(EnodebAcsState):
+    def __init__(
+        self,
+        acs: EnodebAcsStateMachine,
+        when_done: str,
+        when_apply_invasive: str,
+        status_non_zero_allowed: bool = False,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.apply_invasive_transition = when_apply_invasive
+        # Set Params can legally return zero and non zero status
+        # Per tr-196, if there are errors the method should return a fault.
+        # Make flag optional to compensate for existing radios returning non
+        # zero on error.
+        self.status_non_zero_allowed = status_non_zero_allowed
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        if type(message) == models.SetParameterValuesResponse:
+            if not self.status_non_zero_allowed:
+                if message.Status != 0:
+                    raise Tr069Error(
+                        'Received SetParameterValuesResponse with '
+                        'Status=%d' % message.Status,
+                    )
+            self._mark_as_configured()
+            if not self.acs.are_invasive_changes_applied:
+                return AcsReadMsgResult(True, self.apply_invasive_transition)
+            return AcsReadMsgResult(True, self.done_transition)
+        elif type(message) == models.Fault:
+            logger.error(
+                'Received Fault in response to SetParameterValues, '
+                'Code (%s), Message (%s)', message.FaultCode,
+                message.FaultString,
+            )
+            if message.SetParameterValuesFault is not None:
+                for fault in message.SetParameterValuesFault:
+                    logger.error(
+                        'SetParameterValuesFault Param: %s, '
+                        'Code: %s, String: %s', fault.ParameterName,
+                        fault.FaultCode, fault.FaultString,
+                    )
+        return AcsReadMsgResult(False, None)
+
+    def _mark_as_configured(self) -> None:
+        """
+        A successful attempt at setting parameter values means that we need to
+        update what we think the eNB's configuration is to match what we just
+        set the parameter values to.
+        """
+        # Values of parameters
+        name_to_val = get_param_values_to_set(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+            self.acs.data_model,
+        )
+        for name, val in name_to_val.items():
+            magma_val = self.acs.data_model.transform_for_magma(name, val)
+            self.acs.device_cfg.set_parameter(name, magma_val)
+
+        # Values of object parameters
+        obj_to_name_to_val = get_obj_param_values_to_set(
+            self.acs.desired_cfg,
+            self.acs.device_cfg,
+            self.acs.data_model,
+        )
+        for obj_name, name_to_val in obj_to_name_to_val.items():
+            for name, val in name_to_val.items():
+                logger.debug(
+                    'Set obj: %s, name: %s, val: %s', str(obj_name),
+                    str(name), str(val),
+                )
+                magma_val = self.acs.data_model.transform_for_magma(name, val)
+                self.acs.device_cfg.set_parameter_for_object(
+                    name, magma_val,
+                    obj_name,
+                )
+        logger.info('Successfully configured CPE parameters!')
+
+    def state_description(self) -> str:
+        return 'Setting parameter values'
+
+
+class EndSessionState(EnodebAcsState):
+    """ To end a TR-069 session, send an empty HTTP response """
+
+    def __init__(self, acs: EnodebAcsStateMachine):
+        super().__init__()
+        self.acs = acs
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        No message is expected after enodebd sends the eNodeB
+        an empty HTTP response.
+
+        If a device sends an empty HTTP request, we can just
+        ignore it and send another empty response.
+        """
+        if isinstance(message, models.DummyInput):
+            return AcsReadMsgResult(True, None)
+        return AcsReadMsgResult(False, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        request = models.DummyInput()
+        return AcsMsgAndTransition(request, None)
+
+    def state_description(self) -> str:
+        return 'Completed provisioning eNB. Awaiting new Inform.'
+
+
+class EnbSendRebootState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.prev_msg_was_inform = False
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        This state can be transitioned into through user command.
+        All messages received by enodebd will be ignored in this state.
+        """
+        if self.prev_msg_was_inform \
+                and not isinstance(message, models.DummyInput):
+            return AcsReadMsgResult(False, None)
+        elif isinstance(message, models.Inform):
+            self.prev_msg_was_inform = True
+            process_inform_message(
+                message, self.acs.data_model,
+                self.acs.device_cfg,
+            )
+            return AcsReadMsgResult(True, None)
+        self.prev_msg_was_inform = False
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        if self.prev_msg_was_inform:
+            response = models.InformResponse()
+            # Set maxEnvelopes to 1, as per TR-069 spec
+            response.MaxEnvelopes = 1
+            return AcsMsgAndTransition(response, None)
+        logger.info('Sending reboot request to eNB')
+        request = models.Reboot()
+        request.CommandKey = ''
+        self.acs.are_invasive_changes_applied = True
+        return AcsMsgAndTransition(request, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Rebooting eNB'
+
+
+class SendRebootState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.prev_msg_was_inform = False
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        """
+        This state can be transitioned into through user command.
+        All messages received by enodebd will be ignored in this state.
+        """
+        if self.prev_msg_was_inform \
+                and not isinstance(message, models.DummyInput):
+            return AcsReadMsgResult(False, None)
+        elif isinstance(message, models.Inform):
+            self.prev_msg_was_inform = True
+            process_inform_message(
+                message, self.acs.data_model,
+                self.acs.device_cfg,
+            )
+            return AcsReadMsgResult(True, None)
+        self.prev_msg_was_inform = False
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        if self.prev_msg_was_inform:
+            response = models.InformResponse()
+            # Set maxEnvelopes to 1, as per TR-069 spec
+            response.MaxEnvelopes = 1
+            return AcsMsgAndTransition(response, None)
+        logger.info('Sending reboot request to eNB')
+        request = models.Reboot()
+        request.CommandKey = ''
+        return AcsMsgAndTransition(request, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Rebooting eNB'
+
+
+class WaitRebootResponseState(EnodebAcsState):
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        if not isinstance(message, models.RebootResponse):
+            return AcsReadMsgResult(False, None)
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        """ Reply with empty message """
+        return AcsMsgAndTransition(models.DummyInput(), self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Rebooting eNB'
+
+
+class WaitInformMRebootState(EnodebAcsState):
+    """
+    After sending a reboot request, we expect an Inform request with a
+    specific 'inform event code'
+    """
+
+    # Time to wait for eNodeB reboot. The measured time
+    # (on BaiCells indoor eNodeB)
+    # is ~110secs, so add healthy padding on top of this.
+    REBOOT_TIMEOUT = 300  # In seconds
+    # We expect that the Inform we receive tells us the eNB has rebooted
+    INFORM_EVENT_CODE = 'M Reboot'
+
+    def __init__(
+        self,
+        acs: EnodebAcsStateMachine,
+        when_done: str,
+        when_timeout: str,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.timeout_transition = when_timeout
+        self.timeout_timer = None
+        self.timer_handle = None
+
+    def enter(self):
+        self.timeout_timer = StateMachineTimer(self.REBOOT_TIMEOUT)
+
+        def check_timer() -> None:
+            if self.timeout_timer.is_done():
+                self.acs.transition(self.timeout_transition)
+                raise Tr069Error(
+                    'Did not receive Inform response after '
+                    'rebooting',
+                )
+
+        self.timer_handle = \
+            self.acs.event_loop.call_later(
+                self.REBOOT_TIMEOUT,
+                check_timer,
+            )
+
+    def exit(self):
+        self.timer_handle.cancel()
+        self.timeout_timer = None
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        if not isinstance(message, models.Inform):
+            return AcsReadMsgResult(False, None)
+        if not does_inform_have_event(message, self.INFORM_EVENT_CODE):
+            raise Tr069Error(
+                'Did not receive M Reboot event code in '
+                'Inform',
+            )
+        process_inform_message(
+            message, self.acs.data_model,
+            self.acs.device_cfg,
+        )
+        return AcsReadMsgResult(True, self.done_transition)
+
+    def state_description(self) -> str:
+        return 'Waiting for M Reboot code from Inform'
+
+
+class WaitRebootDelayState(EnodebAcsState):
+    """
+    After receiving the Inform notifying us that the eNodeB has successfully
+    rebooted, wait a short duration to prevent unspecified race conditions
+    that may occur w.r.t reboot
+    """
+
+    # Short delay timer to prevent race conditions w.r.t. reboot
+    SHORT_CONFIG_DELAY = 10
+
+    def __init__(self, acs: EnodebAcsStateMachine, when_done: str):
+        super().__init__()
+        self.acs = acs
+        self.done_transition = when_done
+        self.config_timer = None
+        self.timer_handle = None
+
+    def enter(self):
+        self.config_timer = StateMachineTimer(self.SHORT_CONFIG_DELAY)
+
+        def check_timer() -> None:
+            if self.config_timer.is_done():
+                self.acs.transition(self.done_transition)
+
+        self.timer_handle = \
+            self.acs.event_loop.call_later(
+                self.SHORT_CONFIG_DELAY,
+                check_timer,
+            )
+
+    def exit(self):
+        self.timer_handle.cancel()
+        self.config_timer = None
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        return AcsMsgAndTransition(models.DummyInput(), None)
+
+    def state_description(self) -> str:
+        return 'Waiting after eNB reboot to prevent race conditions'
+
+
+class ErrorState(EnodebAcsState):
+    """
+    The eNB handler will enter this state when an unhandled Fault is received.
+
+    If the inform_transition_target constructor parameter is non-null, this
+    state will attempt to autoremediate by transitioning to the specified
+    target state when an Inform is received.
+    """
+
+    def __init__(
+        self, acs: EnodebAcsStateMachine,
+        inform_transition_target: Optional[str] = None,
+    ):
+        super().__init__()
+        self.acs = acs
+        self.inform_transition_target = inform_transition_target
+
+    def read_msg(self, message: Any) -> AcsReadMsgResult:
+        return AcsReadMsgResult(True, None)
+
+    def get_msg(self, message: Any) -> AcsMsgAndTransition:
+        if not self.inform_transition_target:
+            return AcsMsgAndTransition(models.DummyInput(), None)
+
+        if isinstance(message, models.Inform):
+            return AcsMsgAndTransition(
+                models.DummyInput(),
+                self.inform_transition_target,
+            )
+        return AcsMsgAndTransition(models.DummyInput(), None)
+
+    def state_description(self) -> str:
+        return 'Error state - awaiting manual restart of enodebd service or ' \
+               'an Inform to be received from the eNB'
