def perform_delete(self): """ Perform the delete requests """ self.log.debug('perform-delete') try: for me in self._me_tuples: class_id = me[0] entity_id = me[1] frame = OmciFrame(transaction_id=None, message_type=OmciDelete.message_id, omci_message=OmciDelete( entity_class=class_id, entity_id=entity_id)) self.strobe_watchdog() results = yield self._device.omci_cc.send(frame) status = results.fields['omci_message'].fields['success_code'] self.log.debug('perform-delete-status', status=status) # Did it fail, it instance does not exist, not an error if status != RC.Success.value and status != RC.UnknownInstance.value: msg = 'ME: {}, entity: {} failed with status {}'.format( class_id, entity_id, status) raise DeletePMException(msg) self.log.debug('delete-pm-success', class_id=class_id, entity_id=entity_id) self.deferred.callback(self) except Exception as e: self.log.exception('perform-create', e=e) self.deferred.errback(failure.Failure(e))
def sim_receive_commit_image_resp(self, tid, eid, r=0): msg = OmciFrame(transaction_id=tid, message_type=OmciCommitImageResponse.message_id, omci_message=OmciCommitImageResponse(entity_class=0x7, entity_id=eid, result=r)) self.device.omci_cc.receive_message(msg)
def sim_receive_download_section_resp(self, tid, eid, section, r=0): msg = OmciFrame(transaction_id=tid, message_type=OmciDownloadSectionResponse.message_id, omci_message=OmciDownloadSectionResponse( entity_class=0x7, entity_id=eid, result=r, section_number=section)) self.device.omci_cc.receive_message(msg)
def sim_receive_end_sw_download_resp(self, tid, eid, r=0): msg = OmciFrame( transaction_id=tid, message_type=OmciEndSoftwareDownloadResponse.message_id, omci_message=OmciEndSoftwareDownloadResponse(entity_class=0x7, entity_id=eid, result=r, image_number=0x1, instance_id=eid, result0=0x0)) self.device.omci_cc.receive_message(msg)
def sim_receive_start_sw_download_resp(self, tid, eid, r=0): msg = OmciFrame( transaction_id=tid, message_type=OmciStartSoftwareDownloadResponse.message_id, omci_message=OmciStartSoftwareDownloadResponse(entity_class=0x7, entity_id=eid, result=r, window_size=0x1F, image_number=1, instance_id=eid)) self.device.omci_cc.receive_message(msg)
def test_omci_message2(self): self.log.debug("do test_omci_message2") msg = OmciFrame( transaction_id=0x0001, message_type=OmciStartSoftwareDownloadResponse.message_id, omci_message=OmciStartSoftwareDownloadResponse(entity_class=0x7, entity_id=0x0, result=0x0, window_size=0x1F, image_number=1, instance_id=0)) self.log.debug(binascii.hexlify(str(msg)))
def perform_get_missing_attributes(self, missing_attr): """ This method is called when the original Get requests completes with success but not all attributes were returned. This can happen if one or more of the attributes would have exceeded the space available in the OMCI frame. This routine iterates through the missing attributes and attempts to retrieve the ones that were missing. :param missing_attr: (set) Missing attributes """ self.log.debug('perform-get-missing', attrs=missing_attr) results_omci = self._results.fields['omci_message'].fields for index in xrange(16): attr_mask = 1 << index if attr_mask & missing_attr: # Get this attribute frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciGet.message_id, omci_message=OmciGet( entity_class=self._entity_class.class_id, entity_id=self._entity_id, attributes_mask=attr_mask)) try: self.strobe_watchdog() get_results = yield self._device.omci_cc.send(frame) get_omci = get_results.fields['omci_message'].fields if get_omci['success_code'] != RC.Success.value: continue assert attr_mask == get_omci[ 'attributes_mask'], 'wrong attribute' results_omci['attributes_mask'] |= attr_mask if results_omci.get('data') is None: results_omci['data'] = dict() results_omci['data'].update(get_omci['data']) except TimeoutError: self.log.debug('missing-timeout') except Exception as e: self.log.exception('missing-failure', e=e) self.deferred.callback(self)
def test_omci_message(self): self.log.debug("do test_omci_message") r = self.get_omci_msg(self.sw_dwld_resp['tid'], self.sw_dwld_resp['mid'], self.sw_dwld_resp['did'], self.sw_dwld_resp['entity_class'], self.sw_dwld_resp['entity_id'], self.sw_dwld_resp['reason'], self.sw_dwld_resp['window_size'], self.sw_dwld_resp['inst_num'], self.sw_dwld_resp['inst_id'], trailer=self.sw_dwld_resp['trailer'], mic=self.sw_dwld_resp['mic']) data = binascii.unhexlify(r) msg = OmciFrame(data) self.log.debug(binascii.hexlify(str(msg)))
def fix_onu_only_remove_from_onu( self, olt_created, ): """ On ONU, but no longer on OLT/OpenOMCI, delete it """ successes = 0 failures = 0 for cid, eid in olt_created: if self.deferred.called: # Check if task canceled break try: # If in current MIB, had an audit issue, declare it an error # and next audit should clear it up try: current_entry = self._sync_sm.query_mib(class_id=cid, instance_id=eid) except KeyError: # Expected if no other entities with same class present in MIB current_entry = None if current_entry is not None and len(current_entry): self.log.debug('onu-only-in-current', cid=cid, eid=eid) failures += 1 else: # Delete it from the ONU. Assume success frame = OmciFrame(transaction_id=None, message_type=OmciDelete.message_id, omci_message=OmciDelete(entity_class=cid, entity_id=eid)) self._local_deferred = yield self._device.omci_cc.send( frame) self.check_status_and_state(self._local_deferred, 'onu-attribute-update') successes += 1 self._db_updates = 0 except Exception as e: self.log.warn('olt-only-error', e=e) failures += 1 self.strobe_watchdog() returnValue((successes, failures))
def send_omci_identity_frame(self): log.debug('send_omci_identity_frame') message = OmciGet(entity_class=CircuitPack.class_id, entity_id=257, attributes_mask=2048) # TODO fix transaction id frame = OmciFrame(transaction_id=0, message_type=OmciGet.message_id, omci_message=message) omci_frame = PAS5211MsgSendFrame(port_type=PON_PORT_PON, port_id=self.port_id, management_frame=PON_ENABLE, frame=frame) self.send(self.px(omci_frame)) raise self.wait_send_frame()
def fix_attributes_only_on_olt(self, cid, eid, onu_data, olt_db, me_entry): successes = 0 failures = 0 try: # On olt only or in both. Either way OLT wins, first verify that # the OLT version is still the same data that we want to # update on the ONU. Verify the data for the OLT is the same as # at time of audit olt_db_entries = { k: v for k, v in olt_db[cid][eid][ATTRIBUTES_KEY].items() if k in onu_data.keys() } current_entries = self._sync_sm.query_mib( class_id=cid, instance_id=eid, attributes=onu_data.keys()) still_the_same = all( current_entries.get(k) == v for k, v in olt_db_entries.items()) if not still_the_same: returnValue((0, len(onu_data))) # Wait for it to stabilize # OLT data still matches, do the set operations now # while len(onu_data): attributes_mask = me_entry.mask_for(*onu_data.keys()) frame = OmciFrame(transaction_id=None, message_type=OmciSet.message_id, omci_message=OmciSet( entity_class=cid, entity_id=eid, attributes_mask=attributes_mask, data=onu_data)) results = yield self._device.omci_cc.send(frame) self.check_status_and_state(results, 'onu-attribute-update') successes += len(onu_data) self._db_updates = 0 except Exception as e: self.log.exception('attribute-only-fix-onu', e=e, cid=cid, eid=eid) failures += len(onu_data) self.strobe_watchdog() returnValue((successes, failures))
def send_omci_identity_frame(self): # attr_mask |= OMCI_ATTR_BIT(OMCI_CIRCUIT_PACK_ATTR_VENDOR_ID); #message.attributes_mask = 2048 # Entity_id # equip_ind = OMCI_CIRCUIT_PACK_INTEGRATED_EQUIPMENT; # slot_id = 257; # entity_instance = ((equip_ind<<8) | slot_id message = OmciGet(entity_class=CircuitPack.class_id, entity_id=257, attributes_mask=2048) #TODO fix transaction id frame = OmciFrame(transaction_id=0, message_type=OmciGet.message_id, omci_message=message) omci_frame = PAS5211MsgSendFrame(port_type=PON_PORT_PON, port_id=self.port_id, management_frame=PON_ENABLE, frame=frame) self.send(self.px(omci_frame)) raise self.wait_send_frame()
def perform_get_interval(self): """ Sync the time """ self.log.info('perform-get-interval', class_id=self._class_id, entity_id=self._entity_id) device = self.omci_agent.get_device(self.device_id) attr_names = self._counter_attributes.keys() final_results = { 'class_id': self._class_id, 'entity_id': self._entity_id, 'me_name': self._entity.__name__, # Mostly for debugging... 'interval_utc_time': None, # Counters added here as they are retrieved } last_end_time = None while len(attr_names) > 0: # Get as many attributes that will fit. Always include the 1 octet # Interval End Time Attribute and 2 octets for the Entity ID remaining_payload = self._max_payload - 3 attributes = list() for name in attr_names: if self._counter_attributes[name] > remaining_payload: break attributes.append(name) remaining_payload -= self._counter_attributes[name] attr_names = attr_names[len(attributes):] attributes.append('interval_end_time') frame = OmciFrame( transaction_id=None, message_type=OmciGet.message_id, omci_message=OmciGet( entity_class=self._class_id, entity_id=self._entity_id, attributes_mask=self._entity.mask_for(*attributes))) self.log.debug('interval-get-request', class_id=self._class_id, entity_id=self._entity_id) try: self.strobe_watchdog() results = yield device.omci_cc.send(frame) omci_msg = results.fields['omci_message'].fields status = omci_msg['success_code'] end_time = omci_msg['data'].get('interval_end_time') self.log.debug('interval-get-results', class_id=self._class_id, entity_id=self._entity_id, status=status, end_time=end_time) if status != ReasonCodes.Success: raise IntervalDataTaskFailure( 'Unexpected Response Status: {}, Class ID: {}'.format( status, self._class_id)) if last_end_time is None: last_end_time = end_time elif end_time != last_end_time: msg = 'Interval End Time Changed during retrieval from {} to {}'\ .format(last_end_time, end_time) self.log.info('interval-roll-over', msg=msg, class_id=self._class_id) raise IntervalDataTaskFailure(msg) final_results['interval_utc_time'] = datetime.utcnow() for attribute in attributes: final_results[attribute] = omci_msg['data'].get(attribute) except TimeoutError as e: self.log.warn('interval-get-timeout', e=e, class_id=self._class_id) self.deferred.errback(failure.Failure(e)) except Exception as e: self.log.exception('interval-get-failure', e=e, class_id=self._class_id) self.deferred.errback(failure.Failure(e)) # Successful if here self.deferred.callback(final_results)
def fix_olt_only_create_on_onu(self, olt_created, me_map): """ Found on OLT and created by OLT, so create on ONU""" successes = 0 failures = 0 for cid, eid in olt_created: if self.deferred.called: # Check if task canceled break try: # Get current entry, use it if found olt_entry = self._sync_sm.query_mib(class_id=cid, instance_id=eid) me_entry = me_map[cid] if olt_entry is None or len(olt_entry) == 0: successes += 1 # Deleted before task got to run else: # Create it in the ONU. Only set-by-create attributes allowed sbc_data = { k: v for k, v in olt_entry[ATTRIBUTES_KEY].items() if AA.SetByCreate in next(( attr.access for attr in me_entry.attributes if attr.field.name == k), set()) } frame = OmciFrame(transaction_id=None, message_type=OmciCreate.message_id, omci_message=OmciCreate(entity_class=cid, entity_id=eid, data=sbc_data)) self._local_deferred = yield self._device.omci_cc.send( frame) self.check_status_and_state(self._local_deferred, 'olt-create-sbc') successes += 1 self._db_updates = 0 # Try any writeable attributes now (but not set-by-create) writeable_data = { k: v for k, v in olt_entry[ATTRIBUTES_KEY].items() if AA.Writable in next(( attr.access for attr in me_entry.attributes if attr.field.name == k), set()) and AA.SetByCreate not in next((attr.access for attr in me_entry.attributes if attr.field.name == k), set()) } if len(writeable_data): attributes_mask = me_entry.mask_for( *writeable_data.keys()) frame = OmciFrame(transaction_id=None, message_type=OmciSet.message_id, omci_message=OmciSet( entity_class=cid, entity_id=eid, attributes_mask=attributes_mask, data=writeable_data)) self._local_deferred = yield self._device.omci_cc.send( frame) self.check_status_and_state(self._local_deferred, 'olt-set-writeable') successes += 1 except Exception as e: self.log.exception('olt-only-fix', e=e, cid=cid, eid=eid) failures += 1 self.strobe_watchdog() returnValue((successes, failures))
def perform_create(self): """ Perform the create requests """ try: for pm, me in self._me_dict.items(): pm_class_id = pm[0] pm_entity_id = pm[1] me_class_id = me[0] me_entity_id = me[1] upstream = me[2] self.log.debug('create-pm-me', class_id=pm_class_id, entity_id=pm_entity_id) if me_class_id == 0: # Typical/common PM interval format frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciCreate.message_id, omci_message=OmciCreate(entity_class=pm_class_id, entity_id=pm_entity_id, data=dict())) else: # Extended PM interval format. See ITU-T G.988 Section 9.3.32. # Bit 1 - continuous accumulation if set, 15-minute interval if unset # Bit 2 - directionality (0=upstream, 1=downstream) # Bit 3..14 - Reserved # Bit 15 - Use P bits of TCI field to filter # Bit 16 - Use VID bits of TCI field to filter bitmap = 0 if upstream else 1 << 1 data = { 'control_block': [ 0, # Threshold data 1/2 ID me_class_id, # Parent ME Class me_entity_id, # Parent ME Instance 0, # Accumulation disable 0, # TCA Disable bitmap, # Control fields bitmap 0, # TCI 0 # Reserved ] } frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciCreate.message_id, omci_message=OmciCreate(entity_class=pm_class_id, entity_id=pm_entity_id, data=data)) self.strobe_watchdog() try: results = yield self._device.omci_cc.send(frame) except TimeoutError: self.log.warning('perform-create-timeout', me_class_id=me_class_id, me_entity_id=me_entity_id, pm_class_id=pm_class_id, pm_entity_id=pm_entity_id) raise status = results.fields['omci_message'].fields['success_code'] self.log.debug('perform-create-status', status=status) # Did it fail if status != RC.Success.value and status != RC.InstanceExists.value: msg = 'ME: {}, entity: {} failed with status {}'.format( pm_class_id, pm_entity_id, status) raise CreatePMException(msg) self.log.debug('create-pm-success', class_id=pm_class_id, entity_id=pm_entity_id) self.deferred.callback(self) except Exception as e: self.log.exception('perform-create', e=e) self.deferred.errback(failure.Failure(e))
def process_get_table(self, table_attributes): """ Special handling for Get Requests that may require additional 'get_next' operations if a table attribute was requested. """ # Retrieve attributes retrieved so far so we can add to them try: results_omci = self._results.fields['omci_message'].fields if self._results is not None else {} for tbl_attr in table_attributes: attr_mask = self._entity_class.mask_for(tbl_attr) attr_index = self._entity_class.attribute_indices_from_mask(attr_mask)[0] frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciGet.message_id, omci_message=OmciGet( entity_class=self._entity_class.class_id, entity_id=self._entity_id, attributes_mask=attr_mask ) ) # First get will retrieve the size get_results = yield self._device.omci_cc.send(frame) self.strobe_watchdog() if self._results is None: self._results = get_results results_omci = self._results.fields['omci_message'].fields omci_fields = get_results.fields['omci_message'].fields if omci_fields['success_code'] == RC.AttributeFailure.value: # Copy over any failed or unsupported attribute masks for final result results_fields = results_omci.fields['omci_message'].fields unsupported_attr = results_omci.get('unsupported_attributes_mask', 0) or 0 failed_attr = results_omci.get('failed_attributes_mask', 0) or 0 results_fields['unsupported_attributes_mask'] |= unsupported_attr results_fields['failed_attributes_mask'] |= failed_attr if omci_fields['success_code'] != RC.Success.value: raise GetException('Get table attribute failed with status code: {}'. format(omci_fields['success_code'])) eca = self._entity_class.attributes[attr_index] self.log.debug('omcc-get-table-attribute', table_name=eca.field.name) attr_size = omci_fields['data'][eca.field.name + '_size'] if attr_size > self.MAX_TABLE_SIZE: self.log.error('omcc-get-table-huge', count=attr_size, name=eca.field.name) raise ValueError('Huge Table Size: {}'.format(attr_size)) # Start the loop seq_no = 0 data_buffer = '' for offset in xrange(0, attr_size, OmciTableField.PDU_SIZE): frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciGetNext.message_id, omci_message=OmciGetNext( entity_class=self._entity_class.class_id, entity_id=self._entity_id, attributes_mask=attr_mask, command_sequence_number=seq_no ) ) get_results = yield self._device.omci_cc.send(frame) omci_fields = get_results.fields['omci_message'].fields status = omci_fields['success_code'] if status != ReasonCodes.Success.value: raise Exception('get-next-failure table=' + eca.field.name + ' entity_id=' + str(self._entity_id) + ' sqn=' + str(seq_no) + ' omci-status ' + str(status)) # Extract the data num_octets = attr_size - offset if num_octets > OmciTableField.PDU_SIZE: num_octets = OmciTableField.PDU_SIZE data = omci_fields['data'][eca.field.name] data_buffer += data[:num_octets] seq_no += 1 vals = [] while data_buffer: data_buffer, val = eca.field.getfield(None, data_buffer) vals.append(val) # Save off the retrieved data results_omci['attributes_mask'] |= attr_mask results_omci['data'][eca.field.name] = vals self.deferred.callback(self) except TimeoutError as e: self.log.debug('tbl-attr-timeout') self.deferred.errback(failure.Failure(e)) except Exception as e: self.log.exception('tbl-attr-timeout', class_id=self._entity_class.class_id, entity_id=self._entity_id, e=e) self.deferred.errback(failure.Failure(e))
def rx_omci_frame(self, msg): try: frame = OmciFrame(msg.decode('hex')) response = None response_type = self._request_to_response_type( frame.fields['message_type']) transaction_id = frame.fields['transaction_id'] omci_message = frame.fields.get('omci_message') class_id = omci_message.fields.get('entity_class') \ if omci_message is not None else None instance_id = omci_message.fields.get('entity_id') \ if omci_message is not None else None # Look up hardcode responses based on class and instance ID. If found # return the response, otherwise send back an error if response_type is None: status = RC.ProcessingError.value elif class_id is None: status = RC.UnknownEntity.value elif instance_id is None: status = RC.UnknownInstance.value else: status = RC.Success.value try: response_id = response_type.message_id & 0x1f response = self._omci_response[response_id][class_id][ instance_id] if response_id == OP.MibUploadNext.value: # Special case. Need to get requested entry assert isinstance(response, list) pass pass pass pass response.fields['transaction_id'] = transaction_id if 'success_code' in response.fields[ 'omci_message'].fields: response.fields['omci_message'].fields[ 'success_code'] = status if status == RC.Success.value: if response_type.message_id in [ OmciCreateResponse.message_id, OmciDeleteResponse.message_id, OmciSetResponse.message_id ]: self.mib_data_sync += 1 if self.mib_data_sync > 255: self.mib_data_sync = 1 elif response_type.message_id == OmciMibResetResponse.message_id: self.mib_data_sync = 0 except KeyError as e: bad_key = e.args[0] if bad_key == class_id: status = RC.UnknownEntity.value elif bad_key == instance_id: status = RC.UnknownInstance.value else: status = RC.ProcessingError.value if status != RC.Success.value and \ response_type not in [OmciMibUploadResponse, OmciMibUploadNextResponse]: response = OmciFrame(transaction_id=transaction_id, message_type=response_type.message_id, omci_message=response_type( entity_class=class_id, entity_id=instance_id, success_code=status)) return response except Exception as e: pass
def perform_get_missing_attributes(self, missing_attr, table_attributes): """ This method is called when the original Get requests completes with success but not all attributes were returned. This can happen if one or more of the attributes would have exceeded the space available in the OMCI frame or if one of the attributes is a table. This routine iterates through the missing attributes and attempts to retrieve the ones that were missing. Once missing attributes are recovered, the table attributes are requested :param missing_attr: (int) Missing attributes bitmask :param table_attributes: (set) Attributes that need table get/get-next support """ self.log.debug('perform-get-missing', attrs=missing_attr, tbl=table_attributes) # Retrieve missing attributes first (if any) results_omci = self._results.fields['omci_message'].fields try: # Get remaining attributes one at a time for index in range(15, 1, -1): attr_mask = 1 << index if attr_mask & missing_attr: # Get this attribute frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciGet.message_id, omci_message=OmciGet( entity_class=self._entity_class.class_id, entity_id=self._entity_id, attributes_mask=attr_mask ) ) self.strobe_watchdog() get_results = yield self._device.omci_cc.send(frame) get_omci = get_results.fields['omci_message'].fields status = get_omci['success_code'] if status == RC.AttributeFailure.value: unsupported_attr = get_omci.get('unsupported_attributes_mask', 0) or 0 failed_attr = get_omci.get('failed_attributes_mask', 0) or 0 results_omci['unsupported_attributes_mask'] |= unsupported_attr results_omci['failed_attributes_mask'] |= failed_attr continue elif status != RC.Success.value: raise GetException('Get failed with status code: {}'.format(status)) assert attr_mask == get_omci['attributes_mask'], 'wrong attribute' results_omci['attributes_mask'] |= attr_mask if results_omci.get('data') is None: results_omci['data'] = dict() results_omci['data'].update(get_omci['data']) except TimeoutError as e: self.log.debug('missing-timeout') self.deferred.errback(failure.Failure(e)) except Exception as e: self.log.exception('missing-failure', class_id=self._entity_class.class_id, entity_id=self._entity_id, e=e) self.deferred.errback(failure.Failure(e)) # Now any table attributes if len(table_attributes): self.strobe_watchdog() self._local_deferred = reactor.callLater(0, self.process_get_table, table_attributes) returnValue(self._local_deferred) self.deferred.callback(self)
def __init__(self, serial_number, adapter_agent, handler_id): self.serial_number = serial_number self._adapter_agent = adapter_agent # TODO: Remove any unused attributes self._handler_id = handler_id self.mib_data_sync = 0 # Assume at reboot! # NOTE: when creating response frames, use the basic method of constructing # these frames as the encoding created is unit-tested elsewhere self._omci_response = { OP.Get.value: { CircuitPack.class_id: { 257: OmciFrame( transaction_id=0, # Will get replaced message_type=OmciGetResponse.message_id, omci_message=OmciGetResponse( entity_class=CircuitPack.class_id, entity_id=0, success_code=RC.Success.value, attributes_mask=CircuitPack.mask_for( 'number_of_ports'), data=OmciMaskedData( 'value', entity_class=CircuitPack.class_id, attributes_mask=CircuitPack.mask_for( 'number_of_ports')))) }, # Additional OMCI GET request responses here if needed }, OP.Create.value: { # TODO: Create some OMCI CREATE request responses here. # def send_create_gal_ethernet_profile(self, # entity_id, # max_gem_payload_size): # frame = OmciFrame( # transaction_id=self.get_tx_id(), # message_type=OmciCreate.message_id, # omci_message=OmciCreate( # entity_class=GalEthernetProfile.class_id, # entity_id=entity_id, # data=dict( # max_gem_payload_size=max_gem_payload_size # ) # ) # ) # self.send_omci_message(frame) }, OP.Set.value: { # TODO: Create some OMCI SET request responses here. # def send_set_admin_state(self, # entity_id, # admin_state): # data = dict( # administrative_state=admin_state # ) # frame = OmciFrame( # transaction_id=self.get_tx_id(), # message_type=OmciSet.message_id, # omci_message=OmciSet( # entity_class=OntG.class_id, # entity_id=entity_id, # attributes_mask=OntG.mask_for(*data.keys()), # data=data # ) # ) # self.send_omci_message(frame) }, OP.Delete.value: { # TODO: Create some OMCI DELETE responses here. }, OP.MibReset.value: { OntData.class_id: { 0: OmciFrame( transaction_id=0, # Will get replaced message_type=OmciMibResetResponse.message_id, omci_message=OmciMibResetResponse( entity_class=OntData.class_id, entity_id=0, success_code=RC.Success.value)) } }, OP.MibUpload.value: { OntData.class_id: { 0: OmciFrame( transaction_id=0, # Will get replaced message_type=OmciMibUploadResponse.message_id, omci_message=OmciMibUploadResponse( entity_class=OntData.class_id, entity_id=0, number_of_commands= 3 # Should match list size for MibUploadNext below )) } }, # OP.MibUploadNext.value: { # OntData.class_id: { # 0: [ # OmciFrame(transaction_id=0, # message_type=OmciMibUploadNextResponse.message_id, # omci_message=OmciMibUploadNextResponse( # entity_class=OntData.class_id, # entity_id=0, # object_entity_id=0, # TODO: Pick one # object_attributes_mask=0, # TODO: Pick one # object_data=None # TODO: Pick one # )), # OmciFrame(transaction_id=0, # message_type=OmciMibUploadNextResponse.message_id, # omci_message=OmciMibUploadNextResponse( # entity_class=OntData.class_id, # entity_id=0, # object_entity_id=0, # TODO: Pick one # object_attributes_mask=0, # TODO: Pick one # object_data=None # TODO: Pick one # )), # OmciFrame(transaction_id=0, # message_type=OmciMibUploadNextResponse.message_id, # omci_message=OmciMibUploadNextResponse( # entity_class=OntData.class_id, # entity_id=0, # object_entity_id=0, # TODO: Pick one # object_attributes_mask=0, # TODO: Pick one # object_data=None # TODO: Pick one # )), # ] # } # }, OP.Reboot.value: { OntData.class_id: { 0: OmciFrame( transaction_id=0, # Will get replaced message_type=OmciRebootResponse.message_id, omci_message=OmciRebootResponse( entity_class=OntG.class_id, entity_id=0, success_code=RC.Success.value)) } }, }
def perform_create(self): """ Perform the create requests """ self.log.info('perform-create') try: for pm, me in self._me_dict.items(): pm_class_id = pm[0] pm_entity_id = pm[1] me_class_id = me[0] me_entity_id = me[1] upstream = me[2] if me_class_id == 0: # Typical/common PM interval format frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciCreate.message_id, omci_message=OmciCreate( entity_class=pm_class_id, entity_id=pm_entity_id, data=dict() ) ) else: # Extended PM interval format bitmap = 0 if upstream else 1 << 2 data = {'control_block': [ 0, # Threshold data 1/2 ID me_class_id, # Parent ME Class me_entity_id, # Parent ME Instance 0, # Accumulation disable 0, # TCA Disable bitmap, # Control fields bitmap 0, # TCI 0 # Reserved ]} frame = OmciFrame( transaction_id=None, # OMCI-CC will set message_type=OmciCreate.message_id, omci_message=OmciCreate( entity_class=pm_class_id, entity_id=pm_entity_id, data=data ) ) results = yield self._device.omci_cc.send(frame) self.stop_if_not_running() status = results.fields['omci_message'].fields['success_code'] self.log.debug('perform-create-status', status=status) # Did it fail if status != RC.Success.value and status != RC.InstanceExists.value: msg = 'ME: {}, entity: {} failed with status {}'.format(pm_class_id, pm_entity_id, status) raise CreatePMException(msg) self.log.debug('create-pm-success', class_id=pm_class_id, entity_id=pm_entity_id) self.deferred.callback(self) except Exception as e: self.log.exception('perform-create', e=e) self.deferred.errback(failure.Failure(e))
def cb_after_send_omci(self, msg): self.log.debug("cb_after_send_omci") dmsg = OmciFrame(binascii.unhexlify(msg)) tid = dmsg.fields['transaction_id'] mid = dmsg.fields['message_type'] dmsg_body = dmsg.fields['omci_message'] eid = dmsg_body.fields['entity_id'] # print("%X" % dmsg.fields['transaction_id']) # print("%X" % dmsg.fields['message_type']) # print("%X" % OmciActivateImage.message_id) # print("%X" % dmsg_body.fields['entity_id']) if mid == OmciStartSoftwareDownload.message_id: self.log.debug("response start download") self.reactor.callLater(0, self.sim_receive_start_sw_download_resp, tid, eid) elif mid == OmciEndSoftwareDownload.message_id: self.log.debug("response end download") if self._end_image_busy_try > 0: self.reactor.callLater(0, self.sim_receive_end_sw_download_resp, tid, eid, r=6) self._end_image_busy_try -= 1 else: self.reactor.callLater(0, self.sim_receive_end_sw_download_resp, tid, eid) elif mid == OmciDownloadSection.message_id: self.log.debug("receive download section, not respond") elif mid == OmciDownloadSectionLast.message_id: self.log.debug("response download last section") self.reactor.callLater(0, self.sim_receive_download_section_resp, tid, eid, section=dmsg_body.fields["section_number"]) elif mid == OmciActivateImage.message_id: self.log.debug("response activate image") if self._act_image_busy_try > 0: self.reactor.callLater(0, self.sim_receive_activate_image_resp, tid, eid, r=6) self._act_image_busy_try -= 1 else: self.reactor.callLater(0, self.sim_receive_activate_image_resp, tid, eid) self.reactor.callLater(2, self.device.image_agent.onu_bootup) elif mid == OmciCommitImage.message_id: self.log.debug("response commit image") self.reactor.callLater(0, self.sim_receive_commit_image_resp, tid, eid) else: self.log.debug("Unsupported message type", message_type=mid) self.defer = Deferred() self.defer.addCallback(self.cb_after_send_omci) self.adapter_agent.send_omci_defer = self.defer
def _initialize_onu(self, device): device = self.adapter_agent.get_device(device.id) self.adapter_agent.register_for_proxied_messages(device.proxy_address) log.debug("INIT", device=device) # DO things to the ONU # |###[ OmciFrame ]### # | transaction_id= 1 # | message_type= 79 # | omci = 10 # | \omci_message\ # | |###[ OmciMibReset ]### # | | entity_class= 2 # | | entity_id = 0 # | omci_trailer= 40 # OmciMibReset msg = OmciMibReset(entity_class=2, entity_id=0) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciMibReset.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciMibResetResponse not in response: log.error("Failed to perform a MIB reset for {}".format( device.proxy_address)) return # ###[ PAS5211Dot3 ]### # dst = 00:0c:d5:00:01:00 # src = 90:e2:ba:82:f9:77 # len = 22 # ###[ PAS5211FrameHeader ]### # part = 1 # total_parts= 1 # size = 16 # magic_number= 0x1234abcd # ###[ PAS5211MsgHeader ]### # sequence_number= 51 # opcode = 0x3009 # event_type= 0 # channel_id= 0 # onu_id = 0 # onu_session_id= 1 # ###[ PAS5211GetOnuAllocs ]### # nothing = 0 # ###[ Raw ]### # load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' msg = PAS5211GetOnuAllocs() self.adapter_agent.send_proxied_message(device.proxy_address, msg) response = yield self.incoming_messages.get() if PAS5211GetOnuAllocsResponse not in response: log.error("Failed to get alloc ids for {}".format( device.proxy_address)) return # ###[ PAS5211Dot3 ]### # dst = 00:0c:d5:00:01:00 # src = 90:e2:ba:82:f9:77 # len = 30 # ###[ PAS5211FrameHeader ]### # part = 1 # total_parts= 1 # size = 24 # magic_number= 0x1234abcd # ###[ PAS5211MsgHeader ]### # sequence_number= 52 # opcode = 0x3007 # event_type= 0 # channel_id= 0 # onu_id = -1 # onu_session_id= -1 # ###[ PAS5211GetSnInfo ]### # serial_number= 'PMCS\xd5b\x84\xac' # ###[ Raw ]### # load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' msg = PAS5211GetSnInfo(serial_number=device.serial_number) self.adapter_agent.send_proxied_message(device.proxy_address, msg) response = yield self.incoming_messages.get() if PAS5211GetSnInfoResponse not in response: log.error("Failed to get serial number info for {}".format( device.proxy_address)) return # ###[ PAS5211Dot3 ]### # dst = 00:0c:d5:00:01:00 # src = 90:e2:ba:82:f9:77 # len = 22 # ###[ PAS5211FrameHeader ]### # part = 1 # total_parts= 1 # size = 16 # magic_number= 0x1234abcd # ###[ PAS5211MsgHeader ]### # sequence_number= 53 # opcode = 0x3074 # event_type= 0 # channel_id= 0 # onu_id = -1 # onu_session_id= -1 # ###[ PAS5211GetOnusRange ]### # nothing = 0 # ###[ Raw ]### # load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' msg = PAS5211GetOnusRange() self.adapter_agent.send_proxied_message(device.proxy_address, msg) response = yield self.incoming_messages.get() if PAS5211GetOnusRangeResponse not in response: log.error("Failed to get ONU Range for {}".format( device.proxy_address)) return # | ###[ OmciFrame ]### # | transaction_id = 2 # | message_type = 72 # | omci = 10 # | \omci_message \ # | | ###[ OmciSet ]### # | | entity_class = 262 # | | entity_id = 32769 # | | attributes_mask = 32768 # | | data = {'alloc_id': 1000} # | omci_trailer = 40 # OmciSet # TODO: maskdata msg = OmciSet(entity_class=262, entity_id=32769, attributes_mask=32768, data=dict(alloc_id=1000)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciSet.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciSetResponse not in response: log.error("Failed to set alloc id for {}".format( device.proxy_address)) return # length = 44 # port_type = 0 # port_id = 0 # management_frame = 1 # \frame \ # | ###[ OmciFrame ]### # | transaction_id = 3 # | message_type = 68 # | omci = 10 # | \omci_message \ # | | ###[ OmciCreate ]### # | | entity_class = 45 # | | entity_id = 1 # | | data = {'max_age': 5120, 'hello_time': 512, 'priority': 32768, 'port_bridging_ind': 0, # 'spanning_tree_ind': 0, 'unknown_mac_address_discard': 0, 'mac_learning_depth': 128, # 'learning_ind': 0, 'forward_delay': 3840} # | | ###[ Raw ]### # | | load = '\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # | omci_trailer = 40 # Found in method: pmc_omci_mac_bridge_sp_me_create from: PMC_OFAL.c # Params # - priority: The bridge priority set on the LAN card # - max_age: The maximum age for an entry in the spanning tree listing # - hello_time: The time interval between hello packets # - forward_delay: The time that the bridge on the Ethernet card in the ONT retains a packet before forwarding it # - unknown_mac_address_discard: frames with unknown destination addresses will be forwarded to all allowed ports msg = OmciCreate(entity_class=45, entity_id=1, data=dict(max_age=5120, hello_time=512, priority=32768, port_bridging_ind=PON_FALSE, spanning_tree_ind=PON_FALSE, unknown_mac_address_discard=0, mac_learning_depth=128, learning_ind=PON_FALSE, forward_delay=3840)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciCreate.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciCreateResponse not in response: log.error("Failed to set parameter on {}".format( device.proxy_address)) return # |###[ OmciFrame ]### # | transaction_id= 4 # | message_type= 68 # | omci = 10 # | \omci_message\ # | |###[ OmciCreate ]### # | | entity_class= 47 # | | entity_id = 0 # | | data = {'tp_pointer': 257, 'encapsulation_methods': 1, 'port_num': 0, 'port_priority': 10, 'tp_type': 1, 'port_path_cost': 100, 'port_spanning_tree_in': 0, 'lan_fcs_ind': 0, 'bridge_id_pointer': 1} # | omci_trailer= 40 # Found in method: pmc_omci_mac_bridge_pcd_me_create from: PMC_OFAL.c # Params # - port_path_cost: The cost contribution of the port to the path cost towards the spanning tree root bridge # - bridge_id_pointer: MAC bridge controlling the port msg = OmciCreate( entity_class=47, entity_id=0, data=dict( tp_pointer=257, encapsulation_methods=OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC, port_num=0, port_priority=10, tp_type=1, port_path_cost=100, port_spanning_tree_in=PON_FALSE, lan_fcs_ind=OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED, bridge_id_pointer=1)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciCreate.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciCreateResponse not in response: log.error("Failed to set info for {}".format(device.proxy_address)) return # |###[ OmciFrame ]### # | transaction_id= 5 # | message_type= 68 # | omci = 10 # | \omci_message\ # | |###[ OmciCreate ]### # | | entity_class= 171 # | | entity_id = 0 # | | data = {'association_type': 2, 'associated_me_pointer': 257} # | omci_trailer= 40 # Found in method: pmc_omci_evto_create from: PMC_OFAL.c msg = OmciCreate( entity_class=171, entity_id=0, data=dict(association_type= OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI, associated_me_pointer=257)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciCreate.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciCreateResponse not in response: log.error("Failed to set association info for {}".format( device.proxy_address)) return # |###[ OmciFrame ]### # | transaction_id= 6 # | message_type= 72 # | omci = 10 # | \omci_message\ # | |###[ OmciSet ]### # | | entity_class= 171 # | | entity_id = 0 # | | attributes_mask= 47616 # | | data = {'association_type': 2, 'input_tpid': 33024, 'associated_me_pointer': 257, 'downstream_mode': 0, 'output_tpid': 33024} # | omci_trailer= 40 # Found in method: pmc_omci_evto_set from: PMC_OFAL.c msg = OmciSet( entity_class=171, entity_id=0, attributes_mask=47616, data=dict(association_type= OMCI_EX_VLAN_TAG_OCD_ASSOCIATION_TYPE_PPTP_ETH_UNI, input_tpid=33024, associated_me_pointer=257, downstream_mode=OMCI_EX_VLAN_TAG_OCD_DS_MODE_US_INVERSE, output_tpid=33024)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciSet.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciSetResponse not in response: log.error("Failed to set association tpid info for {}".format( device.proxy_address)) return # |###[ OmciFrame ]### # | transaction_id= 7 # | message_type= 68 # | omci = 10 # | \omci_message\ # | |###[ OmciCreate ]### # | | entity_class= 130 # | | entity_id = 1 # | | data = {'tp_pointer': 65535, 'unmarked_frame_option': 1, 'interwork_tp_pointer_for_p_bit_priority_6': 65535, # 'interwork_tp_pointer_for_p_bit_priority_7': 65535, 'interwork_tp_pointer_for_p_bit_priority_4': 65535, # 'interwork_tp_pointer_for_p_bit_priority_5': 65535, 'interwork_tp_pointer_for_p_bit_priority_2': 65535, # 'interwork_tp_pointer_for_p_bit_priority_3': 65535, 'interwork_tp_pointer_for_p_bit_priority_0': 65535, # 'interwork_tp_pointer_for_p_bit_priority_1': 65535, 'tp_type': 0, 'default_p_bit_marking': 0} # | omci_trailer= 40 # Found in method: pmc_omci_8021p_msp_me_create from: PMC_OFAL.c msg = OmciCreate( entity_class=130, entity_id=1, data=dict( tp_pointer=65535, unmarked_frame_option=OMCI_8021P_MSP_UNMARKED_FRAME_TAG_FRAME, interwork_tp_pointer_for_p_bit_priority_6=65535, interwork_tp_pointer_for_p_bit_priority_7=65535, interwork_tp_pointer_for_p_bit_priority_4=65535, interwork_tp_pointer_for_p_bit_priority_5=65535, interwork_tp_pointer_for_p_bit_priority_2=65535, interwork_tp_pointer_for_p_bit_priority_3=65535, interwork_tp_pointer_for_p_bit_priority_0=65535, interwork_tp_pointer_for_p_bit_priority_1=65535, tp_type=OMCI_8021P_MSP_TP_TYPE_NULL, default_p_bit_marking=0)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciCreate.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciCreateResponse not in response: log.error("Failed to set interwork info for {}".format( device.proxy_address)) return # |###[ OmciFrame ]### # | transaction_id= 8 # | message_type= 68 # | omci = 10 # | \omci_message\ # | |###[ OmciCreate ]### # | | entity_class= 130 # | | entity_id = 1 # | | data = {'tp_pointer': 1, 'encapsulation_methods': 1, 'port_num': 1, 'port_priority': 3, 'tp_type': 5, 'port_path_cost': 32, 'port_spanning_tree_in': 1, 'lan_fcs_ind': 0, 'bridge_id_pointer': 1} # | omci_trailer= 40 # Found in method: pmc_omci_mac_bridge_pcd_me_create from: PMC_OFAL.c # Params # - port_path_cost: The cost contribution of the port to the path cost towards the spanning tree root bridge # - bridge_id_pointer: MAC bridge controlling the port msg = OmciCreate( entity_class=130, entity_id=1, data=dict( tp_pointer=1, encapsulation_methods=OMCI_MAC_BRIDGE_PCD_ENCAP_METHOD_LLC, port_num=1, port_priority=3, tp_type=5, port_path_cost=32, port_spanning_tree_in=PON_TRUE, lan_fcs_ind=OMCI_MAC_BRIDGE_PCD_LANFCS_FORWARDED, bridge_id_pointer=1)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciCreate.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(self, device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciCreateResponse not in response: log.error("Failed to set encap info for {}".format( device.proxy_address)) return # |###[ OmciFrame ]### # | transaction_id= 9 # | message_type= 68 # | omci = 10 # | \omci_message\ # | |###[ OmciCreate ]### # | | entity_class= 268 # | | entity_id = 1 # | | data = {'priority_queue_pointer_downstream': 0, 'direction': 3, 'tcont_pointer': 32769, 'traffic_descriptor_profile_pointer': 0, 'traffic_management_pointer_upstream': 4, 'port_id': 1000} # | omci_trailer= 40 # Found in method: pmc_omci_gem_nctp_create from: PMC_OFAL.c msg = OmciCreate(entity_class=268, entity_id=1, data=dict(priority_queue_pointer_downstream=0, direction=GEM_DIR_BIDIRECT, tcont_pointer=32769, traffic_descriptor_profile_pointer=0, traffic_management_pointer_upstream=4, port_id=1000)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciCreate.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciCreateResponse not in response: log.error("Failed to priority queue for {}".format( device.proxy_address)) return # |###[ OmciFrame ]### # | transaction_id= 10 # | message_type= 68 # | omci = 10 # | \omci_message\ # | |###[ OmciCreate ]### # | | entity_class= 266 # | | entity_id = 1 # | | data = {'gem_port_network_ctp_pointer': 1, 'gal_profile_pointer': 0, 'service_profile_pointer': 1, 'interworking_option': 5, 'interworking_tp_pointer': 0} # | omci_trailer= 40 # Found in method: pmc_omci_gem_iwtp_me_create from: PMC_OFAL.c # Params # - gem_port_network_ctp_pointer: An instance identifier of the GEM Port Network CTP that is associated with this GEM Interworking Termination Point # - service_profile_pointer: The service profile type and a pointer to the instance of a service profile # - interworking_tp_pointer: Used for in the case of Circuit Emulation Services and 802.1p mapper service # - gal_profile_pointer: A pointer to an instance of the GAL Profile msg = OmciCreate( entity_class=266, entity_id=1, data=dict(gem_port_network_ctp_pointer=1, gal_profile_pointer=0, service_profile_pointer=1, interworking_option=OMCI_GEM_IWTP_IW_OPT_8021P_MAPPER, interworking_tp_pointer=0)) frame = OmciFrame(transaction_id=self.trangen.next(), message_type=OmciCreate.message_id, omci_message=msg) self.adapter_agent.send_proxied_message(device.proxy_address, frame) response = yield self.incoming_messages.get() if OmciCreateResponse not in response: log.error("Failed to set gem info for {}".format( device.proxy_address)) return