def read_msg(self, message: Any) -> Optional[str]: """ In this case, we assume that we already know things such as the manufacturer OUI, and also the SW-version of the eNodeB which is sending the Inform message, so we don't process the message. We just check that we're getting the right message type that we expect. Returns: InformResponse """ if type(message) == models.Fault: raise Tr069Error( 'ACS in WaitInform state. Received a Fault message. ' '(faultstring = %s)' % message.FaultString) elif not isinstance(message, models.Inform): raise ConfigurationError( 'ACS in WaitInform state. Expected an Inform message. ' + 'Received a %s message.' % type(message)) is_correct_event = False for event in message.Event.EventStruct: logging.debug('Inform event: %s', event.EventCode) if event.EventCode == self.INFORM_EVENT_CODE: # Mark eNodeB as unconfigured, since some config params # are reset on reboot (e.g. perf mgmt enable) logging.info('eNodeB booting - reconfig required') self.acs.device_cfg = EnodebConfiguration(self.acs.data_model) is_correct_event = True if not is_correct_event: raise Tr069Error('Did not receive 1 BOOT event code in ' 'Inform') process_inform_message(message, self.acs.device_name, self.acs.data_model, self.acs.device_cfg) return None
def read_msg(self, message: Any) -> Optional[str]: """ 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: raise Tr069Error('Unexpected response type: %s' % type(message)) 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 None if len( get_all_objects_to_add(self.acs.desired_cfg, self.acs.device_cfg)) is 0: return self.skip_transition return self.add_obj_transition
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 read_msg(self, message: Any) -> Optional[str]: if type(message) == models.RebootResponse: pass elif type(message) == models.Fault: raise Tr069Error('Received Fault in response to Reboot ' '(faultstring = %s)' % message.FaultString) else: raise Tr069Error('Unexpected response type: %s' % type(message)) return self.done_transition
def assert_is_msg_type_and_not_fault( message: Tr069ComplexModel, type_: Type[Tr069ComplexModel], ) -> None: if type(message) == models.Fault: raise Tr069Error('Received Fault in response to GetParameterValues ' '(faultstring = %s)' % message.FaultString) elif type(message) != type_: raise Tr069Error('Unexpected response type: %s' % type(message))
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', )
def get_msg(self) -> 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 = [] logging.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 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 _handle_tr069_message(cls, ctx: Any, message: ComplexModelBase) -> Any: if not cls.state_machine(): raise Tr069Error('ACS not given eNB state machine') # Log incoming msg if hasattr(message, 'as_dict'): logging.debug('Handling TR069 message: %s', str(type(message))) else: logging.debug('Handling TR069 message.') try: req = cls.state_machine().handle_tr069_message(message) except IncorrectDeviceHandlerError as err: logging.warning('Incorrect device_handler! Switching to : %s', str(err.device_name)) cls.set_state_machine(cls.get_new_state_machine(err.device_name)) # Retry with the new state machine req = cls.state_machine().handle_tr069_message(message) # Log outgoing msg if hasattr(req, 'as_dict'): logging.debug('Sending TR069 message: %s', str(req.as_dict())) else: logging.debug('Sending TR069 message.') # Set return message name ctx.descriptor.out_message.Attributes.sub_name = req.__class__.__name__ # Set header ctx.out_header = models.ID(mustUnderstand='1') ctx.out_header.Data = 'null' req_out = cls._generate_acs_to_cpe_request_copy(req) return req_out
def read_msg(self, message: Any) -> Optional[str]: if type(message) == models.Fault: logger.error('Received Fault in response to SetParameterValues') 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, ) raise Tr069Error( 'Received Fault in response to SetParameterValues ' '(faultstring = %s)' % message.FaultString, ) elif not isinstance(message, models.SetParameterValuesResponse): return AcsReadMsgResult(False, None) if message.Status != 0: raise Tr069Error( 'Received SetParameterValuesResponse with ' 'Status=%d' % message.Status, ) param_name = ParameterName.ADMIN_STATE desired_admin_value = \ self.acs.desired_cfg.get_parameter(param_name) \ and self.admin_value magma_value = \ self.acs.data_model.transform_for_magma( param_name, desired_admin_value, ) self.acs.device_cfg.set_parameter(param_name, magma_value) if len( get_all_objects_to_delete( self.acs.desired_cfg, self.acs.device_cfg, ), ) > 0: return AcsReadMsgResult(True, self.del_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) else: return AcsReadMsgResult(True, self.done_transition)
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 read_msg(self, message: Any) -> Optional[str]: if type(message) == models.Fault: logging.error('Received Fault in response to SetParameterValues') if message.SetParameterValuesFault is not None: for fault in message.SetParameterValuesFault: logging.error( 'SetParameterValuesFault Param: %s, Code: %s, String: %s', fault.ParameterName, fault.FaultCode, fault.FaultString) raise Tr069Error( 'Received Fault in response to SetParameterValues ' '(faultstring = %s)' % message.FaultString) elif not isinstance(message, models.SetParameterValuesResponse): return AcsReadMsgResult(False, None) if message.Status != 0: raise Tr069Error('Received SetParameterValuesResponse with ' 'Status=%d' % message.Status) return AcsReadMsgResult(True, self.done_transition)
def read_msg(self, message: Any) -> AcsReadMsgResult: if type(message) == models.RebootResponse: pass elif type(message) == models.Fault: raise Tr069Error('Received Fault in response to Reboot ' '(faultstring = %s)' % message.FaultString) else: return AcsReadMsgResult(False, None) return AcsReadMsgResult(True, self.done_transition)
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.device_name, self.acs.data_model, self.acs.device_cfg) return AcsReadMsgResult(True, self.done_transition)
def read_msg(self, message: Any) -> Optional[str]: if type(message) == models.Fault: logging.error('Received Fault in response to SetParameterValues') if message.SetParameterValuesFault is not None: for fault in message.SetParameterValuesFault: logging.error( 'SetParameterValuesFault Param: %s, Code: %s, String: %s', fault.ParameterName, fault.FaultCode, fault.FaultString) raise Tr069Error( 'Received Fault in response to SetParameterValues ' '(faultstring = %s)' % message.FaultString) elif not isinstance(message, models.SetParameterValuesResponse): raise Tr069Error( 'ACS in WaitEnableAdmin state. ' 'Unexpected response type: %s' % type(message)) if message.Status != 0: raise Tr069Error('Received SetParameterValuesResponse with ' 'Status=%d' % message.Status) return self.done_transition
def read_msg(self, message: Any) -> Optional[str]: if type(message) == models.Inform: is_correct_event = False for event in message.Event.EventStruct: logging.debug('Inform event: %s', event.EventCode) if event.EventCode == self.INFORM_EVENT_CODE: is_correct_event = True if not is_correct_event: raise Tr069Error('Did not receive M Reboot event code in ' 'Inform') elif type(message) == models.Fault: # eNodeB may send faults for no apparent reason before rebooting return None else: raise Tr069Error('Unexpected response type: %s' % type(message)) process_inform_message(message, self.acs.device_name, self.acs.data_model, self.acs.device_cfg) return self.done_transition
def read_msg(self, message: Any) -> Optional[str]: if type(message) == models.SetParameterValuesResponse: if message.Status != 0: raise Tr069Error('Received SetParameterValuesResponse with ' 'Status=%d' % message.Status) self._mark_as_configured() return self.done_transition elif type(message) == models.Fault: logging.error('Received Fault in response to SetParameterValues') if message.SetParameterValuesFault is not None: for fault in message.SetParameterValuesFault: logging.error( 'SetParameterValuesFault Param: %s, ' 'Code: %s, String: %s', fault.ParameterName, fault.FaultCode, fault.FaultString) raise Tr069Error( 'Received Fault in response to SetParameterValues ' '(faultstring = %s)' % message.FaultString) else: raise Tr069Error('Unexpected response type: %s' % type(message))
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 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 read_msg(self, message: Any) -> AcsReadMsgResult: if type(message) == models.Inform: is_correct_event = False for event in message.Event.EventStruct: logging.debug('Inform event: %s', event.EventCode) if event.EventCode == self.INFORM_EVENT_CODE: is_correct_event = True if not is_correct_event: raise Tr069Error('Did not receive M Reboot event code in ' 'Inform') elif type(message) == models.Fault: # eNodeB may send faults for no apparent reason before rebooting return AcsReadMsgResult(True, None) else: return AcsReadMsgResult(False, None) self.received_inform = True process_inform_message(message, self.acs.device_name, self.acs.data_model, self.acs.device_cfg) return AcsReadMsgResult(True, None)
def read_msg(self, message: Any) -> Optional[str]: """ 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, ) logging.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: raise Tr069Error('Unexpected response type: %s' % type(message)) if get_optional_param_to_check(self.acs.data_model) is not None: return None return self.done_transition