def __init__(self, owner: 'OmhHandler', me: ME, attr_names: Optional[Tuple[str, ...]] = None, extended : bool = False): """ Args: owner: request owner me: ME to be sent extended: pass True to generate an extended OMCI message """ assert self.name.lower() in me.actions super().__init__(self.action, me, True, False, extended, owner) if attr_names is None or logger.level <= logging.DEBUG: assigned_attr_numbers = me.attr_numbers(assigned_only=True) if attr_names is None: attr_names = assigned_attr_numbers mask = 0 for an in attr_names: mask |= me.attr(an).mask # Check that all assigned attributes are being set. # It adds an overhead, so, do it only when in debug mode if logger.level <= logging.DEBUG and attr_names is not assigned_attr_numbers: for an in assigned_attr_numbers: if (me.attr(an).mask & mask) == 0 and not me.attr_is_encoded(an): logger.warning("Attribute {} is assigned but is not going to be set".format(me.attr(an).name)) self.set_attr_mask(mask) self._opt_attrs_mask = 0 self._attr_exec_mask = 0
def encode_attributes(self, msg : RawMessage, encode_values: bool = True, table_length : bool = False, encode_me : ME = None) -> RawMessage: # Pack content encode_me = (encode_me is None) and self._me content = bytearray() max_content_len = self._total_len - len(msg) mask = self._remaining_attr_mask idx = 15 while mask != 0: while mask & (1 << idx) == 0: idx -= 1 attr_idx = 16 - idx # attribute mask counts from MSB attr = encode_me.attr(attr_idx) # For some requests table attribute size must be encoded as 4 byte number instead of the actual table data. # XXX table support needs to be added. For now just encode table record size size = (table_length and attr.is_table) and 4 or attr.size if size > max_content_len: break max_content_len -= size if encode_values: if table_length and attr.is_table: value = (attr.name in self._metadata) and self._metadata[attr.name] or attr.size content += NumberDatum(4).encode(value) else: content += encode_me.attr_encode(attr_idx) mask &= ~(1 << idx) self._content_len = len(content) self._remaining_attr_mask = mask return content
def _enable_uni(self, uni: ME) -> OMHStatus: """Enable UNI""" if uni.admin_state == 'UNLOCK': return OMHStatus.OK uni = copy.deepcopy(uni) uni.admin_state = 'UNLOCK' return self.transaction(SetAction(self, uni, ('admin_state',)))
def decode_attributes(self, msg: RawMessage, offset : int, attr_mask: int, table_length : bool = False, decode_me : ME = None) -> bool: """Decode message attributes""" decode_me = decode_me is None and self._me or decode_me len = self._content_len mask = attr_mask max_attr_idx = decode_me.num_attrs - 1 idx = 15 while mask != 0: while mask & (1 << idx) == 0: idx -= 1 attr_idx = 16 - idx # attribute mask counts from MSB if attr_idx > max_attr_idx: logger.warning("decode_attributes: invalid attr bit {} in the mask for {}".format(attr_idx, decode_me.name)) return False # Table attributes are skipped for GET requests. 4-byte table attribute length is returned instead # It is stored in metadata dict {attr_name: value} attr = decode_me.attr(attr_idx) size = (attr.is_table and table_length) and 4 or attr.size if size > len: logger.warning("decode_attributes: message is too short. Can't decode attribute {}".format(attr.name)) return False try: if attr.is_table and table_length: value, offset = NumberDatum(4).decode(msg, offset) self._metadata[attr.name] = value else: value, offset = attr.data_type.decode(msg, offset) decode_me.set_attr_value(attr_idx, value, True) except: logger.warning("decode_attributes: error when decoding {}.{} value {}".format( decode_me.name, attr.name, msg[offset:offset+size])) return False len -= size mask &= ~(1 << idx) self._remaining_attr_mask &= ~attr_mask return True
def __init__(self, owner: 'OmhHandler', me: ME, extended: bool = False): """ Args: owner: request owner me: ME to be sent extended: pass True to generate an extended OMCI message """ assert self.name.lower() in me.actions super().__init__(self.action, me, True, False, extended, owner) self.set_attr_mask(me.attr_mask(access='C')) self._attr_exec_mask = 0
def __init__(self, owner: 'OmhHandler' = None, me: ME = None, attr_names: Optional[Tuple[str, ...]] = None, extended: bool = False): """ Args: owner: request owner me: ME to be sent attr_names: optional list of arguments to be set. If None, all assigned me attributes will be set extended: pass True to generate an extended OMCI message """ assert me is not None assert self.name.lower() in me.actions super().__init__(self.action, me, True, False, extended, owner) if attr_names is None: attr_names = me.attr_numbers() mask = 0 for an in attr_names: mask |= me.attr(an).mask self.set_attr_mask(mask) self._opt_attrs_mask = 0 self._attr_exec_mask = 0