Пример #1
0
 def append_to_transfer_buffer(self, frame_or_notification):
     if self._transfer_buffer is None:
         self._transfer_buffer = RafProviderToUserPdu()['rafTransferBuffer']
         self._release_timer = reactor.callLater(
             self.factory.container.si_config[self._inst_id]
             ['latency_limit'], self._send_transfer_buffer)
     if 'data' in frame_or_notification:
         if self.factory.container.remote_peers[
                 self.factory.container.si_config[self._inst_id]
             ['initiator_id']]['authentication_mode'] == 'ALL':
             frame_or_notification['invokerCredentials'][
                 'used'] = make_credentials(
                     self.factory.container.local_id,
                     self.factory.container.local_password)
         else:
             frame_or_notification['invokerCredentials']['unused'] = None
         frame_or_notification['dataLinkContinuity'] = self._data_continuity
         frame_or_notification['privateAnnotation']['null'] = None
         self._number_of_frames_delivered += 1
         if str(frame_or_notification['deliveredFrameQuality']) == 'good':
             self._number_of_error_free_frames_delivered += 1
         self._data_continuity = 0
         # ToDo Data link continuity
     elif 'notification' in frame_or_notification:
         if self.factory.container.remote_peers[
                 self.factory.container.si_config[self._inst_id]
             ['initiator_id']]['authentication_mode'] == 'ALL':
             frame_or_notification['invokerCredentials'][
                 'used'] = make_credentials(
                     self.factory.container.local_id,
                     self.factory.container.local_password)
         else:
             frame_or_notification['invokerCredentials']['unused'] = None
     else:
         raise Exception('Bad Frame')
     if self.print_frames is True:
         logger.debug(frame_or_notification)
     if len(self._transfer_buffer) < (self.factory.container.si_config[
             self._inst_id]['transfer_buffer_size']):
         self._transfer_buffer.setComponentByPosition(len(
             self._transfer_buffer),
                                                      frame_or_notification,
                                                      matchTags=False)
     else:
         pass
         # ToDo generate dropped notification
     if len(self._transfer_buffer) == self.factory.container.si_config[
             self._inst_id]['transfer_buffer_size']:
         self._send_transfer_buffer()
Пример #2
0
 def _send_status_report(self):
     if self.factory.container.si_config[self._inst_id]['state'] not in {
             'ready', 'active'
     }:
         logger.error('Can not send status report in state: {}'.format(
             self.factory.container.si_config[self._inst_id]['state']))
         return
     pdu_invoc = RafProviderToUserPdu()['rafStatusReportInvocation']
     if self.factory.container.remote_peers[
             self.factory.container.si_config[self._inst_id]
         ['initiator_id']]['authentication_mode'] == 'ALL':
         pdu_invoc['invokerCredentials']['used'] = make_credentials(
             self.factory.container.local_id,
             self.factory.container.local_password)
     else:
         pdu_invoc['invokerCredentials']['unused'] = None
     pdu_invoc[
         'errorFreeFrameNumber'] = self._number_of_error_free_frames_delivered
     pdu_invoc['deliveredFrameNumber'] = self._number_of_frames_delivered
     pdu_invoc['frameSyncLockStatus'] = self._frame_sync_lock_status
     pdu_invoc['symbolSyncLockStatus'] = self._symbol_sync_lock_status
     pdu_invoc['subcarrierLockStatus'] = self._subcarrier_lock_status
     pdu_invoc['carrierLockStatus'] = self._carrier_lock_status
     pdu_invoc['productionStatus'] = self._production_status
     self._send_pdu(pdu_invoc)
     if self._report_timer is not None:
         if self._report_timer.called == 1:
             self._report_timer = reactor.callLater(
                 self.factory.container.si_config[self._inst_id]
                 ['report_cycle'], self._send_status_report)
Пример #3
0
    def _start_invocation_handler(self, pdu):
        logger.debug('Start Invocation received!')
        if self.factory.container.si_config[
                self._inst_id]['state'] is not 'ready':
            logger.error('Invalid state transition')
            self.peer_abort()
        else:
            pdu = pdu['cltuStartInvocation']
            if 'used' in pdu['invokerCredentials']:
                self._invoker_credentials = pdu['invokerCredentials']['used']
            else:
                self._invoker_credentials = None
            self._invoke_id = int(pdu['invokeId'])
            self.first_cltu_identification = pdu['firstCltuIdentification']
            pdu_return = CltuProviderToUserPdu()['cltuStartReturn']
            if self.factory.container.remote_peers[
                    self._initiator_id]['authentication_mode'] == 'ALL':
                pdu_return['performerCredentials']['used'] = make_credentials(
                    self.factory.container.local_id,
                    self.factory.container.local_password)
            else:
                pdu_return['performerCredentials']['unused'] = None
            pdu_return['invokeId'] = self._invoke_id

            if self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == \
                'ALL' and not check_invoke_credentials(self._invoker_credentials, self._initiator_id,
                                                       str(self.factory.container.remote_peers[
                                                               str(self._initiator_id)]['password'])):
                pdu_return['result']['negativeResult'][
                    'common'] = 'otherReason'
            else:
                start_radiation_time = str(dt.datetime.utcnow())
                str_time = dt.datetime.strptime(start_radiation_time,
                                                '%Y-%m-%d %H:%M:%S.%f')
                time_days = (str_time - dt.datetime(1958, 1, 1)).days
                time_ms = (str_time - dt.datetime(str_time.year, str_time.month, str_time.day)).seconds \
                          * 1000 + ((str_time - dt.datetime(str_time.year, str_time.month,
                                                            str_time.day)).microseconds // 1000)
                time_micro = (
                    (str_time - dt.datetime(str_time.year, str_time.month,
                                            str_time.day)).microseconds % 1000)
                start_radiation_time = struct.pack('!HIH', time_days, time_ms,
                                                   time_micro)
                pdu_return['result']['positiveResult']['startRadiationTime'][
                    'ccsdsFormat'] = start_radiation_time
                pdu_return['result']['positiveResult']['stopRadiationTime'][
                    'undefined'] = None
            self._send_pdu(pdu_return)
            if 'negativeResult' not in pdu_return['result']:
                self.factory.container.si_config[
                    self._inst_id]['state'] = 'active'
Пример #4
0
 def _send_status_report(self):
     if self.factory.container.si_config[self._inst_id]['state'] not in {
             'ready', 'active'
     }:
         logger.error('Can not send status report in state: {}'.format(
             self.factory.container.si_config[self._inst_id]['state']))
         return
     pdu_invoc = CltuProviderToUserPdu()['cltuStatusReportInvocation']
     if self.factory.container.remote_peers[
             self.factory.container.si_config[self._inst_id]
         ['initiator_id']]['authentication_mode'] == 'ALL':
         pdu_invoc['invokerCredentials']['used'] = make_credentials(
             self.factory.container.local_id,
             self.factory.container.local_password)
     else:
         pdu_invoc['invokerCredentials']['unused'] = None
     if self._cltu_last_processed is None:
         pdu_invoc['cltuLastProcessed']['noCltuProcessed'] = None
     else:
         pdu_invoc['cltuLastProcessed']['cltuProcessed'][
             'cltuIdentification'] = self.cltu_identification
         pdu_invoc['cltuLastProcessed']['cltuProcessed']['radiationStartTime']['known']['ccsdsFormat'] = \
             self.last_radiation_start_time
         pdu_invoc['cltuLastProcessed']['cltuProcessed'][
             'cltuStatus'] = 'radiated'  # ToDo: Relate to something
     if self._cltu_last_ok is None:
         pdu_invoc['cltuLastOk']['noCltuOk'] = None
     else:
         pdu_invoc['cltuLastOk']['cltuOk'][
             'cltuIdentification'] = self.cltu_identification
         pdu_invoc['cltuLastOk']['cltuOk']['radiationStopTime']['ccsdsFormat'] = \
             self.last_radiation_stop_time
     pdu_invoc['cltuProductionStatus'] = self._cltu_production_status
     pdu_invoc['uplinkStatus'] = self._uplink_status
     pdu_invoc['numberOfCltusReceived'] = self._number_of_cltus_received
     pdu_invoc['numberOfCltusProcessed'] = self._number_of_cltus_processed
     pdu_invoc['numberOfCltusRadiated'] = self._number_of_cltus_radiated
     pdu_invoc['cltuBufferAvailable'] = self._cltu_buffer_availiable
     self._send_pdu(pdu_invoc)
     if self._report_timer is not None:
         if self._report_timer.called == 1:
             self._report_timer = reactor.callLater(
                 self.factory.container.si_config[self._inst_id]
                 ['report_cycle'], self._send_status_report)
Пример #5
0
 def _stop_invocation_handler(self, pdu):
     logger.debug('Stop Invocation received!')
     if self.factory.container.si_config[
             self._inst_id]['state'] is not 'active':
         logger.error('Invalid state transition')
         self.peer_abort()
     else:
         pdu = pdu['rafStopInvocation']
         pdu_return = RafProviderToUserPdu()['rafStopReturn']
         if 'used' in pdu['invokerCredentials']:
             self._invoker_credentials = pdu['invokerCredentials']['used']
             if check_invoke_credentials(
                     self._invoker_credentials, self._initiator_id,
                     str(self.factory.container.remote_peers[str(
                         self._initiator_id)]['password'])):
                 pdu_return['credentials']['used'] = make_credentials(
                     self.factory.container.local_id,
                     str(self.factory.container.remote_peers[str(
                         self._initiator_id)]['password']))
         else:
             pdu_return['credentials']['unused'] = None
             self._invoker_credentials = None
         self._invoke_id = int(pdu['invokeId'])
         pdu_return['invokeId'] = self._invoke_id
         # ToDo: pdu_return['result']['negative'] = 'duplicate Invoke-ID'
         # ToDo: pdu_return['result']['negative'] = 'other reason'
         pdu_return['result']['positiveResult'] = None
         self._send_pdu(pdu_return)
         if 'positiveResult' in pdu_return['result']:
             self.factory.container.si_config[
                 self._inst_id]['state'] = 'ready'
             self.factory.container.si_config[self._inst_id]['requested_frame_quality'] = \
                 self.factory.container.si_config[self._inst_id]['permitted_frame_quality'][0]
             self._data_continuity = -1
             self.factory.container.data_endpoints[0].send_command(
                 'stop-telemetry', [])
             if self._release_timer is not None:
                 if (self._release_timer.called
                         == 1) or (self._release_timer.cancelled == 1):
                     self._release_timer = None
                 else:
                     self._release_timer.cancel()
                     self._release_timer = None
Пример #6
0
 def _unbind_invocation_handler(self, pdu):
     logger.debug('Unbind Invocation received!')
     if self.factory.container.si_config[self._inst_id]['state'] != 'ready':
         logger.error('Invalid state transition')
         self.peer_abort()
     else:
         if self._service_type is 'rtnAllFrames':
             pdu = pdu['rafUnbindInvocation']
             pdu_return = RafProviderToUserPdu()['rafUnbindReturn']
         elif self._service_type is 'fwdCltu':
             pdu = pdu['cltuUnbindInvocation']
             pdu_return = CltuProviderToUserPdu()['cltuUnbindReturn']
         # ToDo implement more service types
         if self.factory.container.remote_peers[
                 self._initiator_id]['authentication_mode'] != 'ALL':
             pdu_return['responderCredentials']['unused'] = None
         else:
             pdu_return['responderCredentials']['used'] = make_credentials(
                 self.factory.container.local_id,
                 self.factory.container.local_password)
         pdu_return['result']['positive'] = None
         self._send_pdu(pdu_return)
         if ('positive'
                 in pdu_return['result']) and (self.__class__
                                               is not CommonProtocol):
             self.factory.container.si_config[
                 self._inst_id]['state'] = 'unbound'
             self.factory.container.si_config[
                 self._inst_id]['report_cycle'] = None
             if (self._release_timer is not None) \
                     and (self._release_timer.called != 1) \
                     and (self._release_timer.cancelled != 1):
                 self._release_timer.cancel()
                 self._release_timer = None
             if (self._report_timer is not None) \
                     and (self._report_timer.called != 1) \
                     and (self._report_timer.cancelled != 1):
                 self._report_timer.cancel()
                 self._report_timer = None
         logger.debug('Unbind reason: {}'.format(str(pdu['unbindReason'])))
Пример #7
0
 def _stop_invocation_handler(self, pdu):
     logger.debug('Stop Invocation received!')
     if self.factory.container.si_config[
             self._inst_id]['state'] is not 'active':
         logger.error('Invalid state transition')
         self.peer_abort()
     else:
         pdu = pdu['cltuStopInvocation']
         pdu_return = CltuProviderToUserPdu()['cltuStopReturn']
         if 'used' in pdu['invokerCredentials']:
             self._invoker_credentials = pdu['invokerCredentials']['used']
             if check_invoke_credentials(
                     self._invoker_credentials, self._initiator_id,
                     str(self.factory.container.remote_peers[str(
                         self._initiator_id)]['password'])):
                 pdu_return['credentials']['used'] = make_credentials(
                     self.factory.container.local_id,
                     str(self.factory.container.remote_peers[str(
                         self._initiator_id)]['password']))
         else:
             pdu_return['credentials']['unused'] = None
             self._invoker_credentials = None
         self._invoke_id = int(pdu['invokeId'])
         pdu_return['invokeId'] = self._invoke_id
         pdu_return['result']['positiveResult'] = None
         self._send_pdu(pdu_return)
         if 'positiveResult' in pdu_return['result']:
             self.factory.container.si_config[
                 self._inst_id]['state'] = 'ready'
             if self._release_timer is not None:
                 if (self._release_timer.called
                         == 1) or (self._release_timer.cancelled == 1):
                     self._release_timer = None
                 else:
                     self._release_timer.cancel()
                     self._release_timer = None
Пример #8
0
    def _start_invocation_handler(self, pdu):
        logger.debug('Start Invocation received!')
        if self.factory.container.si_config[
                self._inst_id]['state'] is not 'ready':
            logger.error('Invalid state transition')
            self.peer_abort()
        else:
            pdu = pdu['rafStartInvocation']
            if 'used' in pdu['invokerCredentials']:
                self._invoker_credentials = pdu['invokerCredentials']['used']
            else:
                self._invoker_credentials = None
            self._invoke_id = int(pdu['invokeId'])
            if 'undefined' in pdu['startTime']:
                self.start_time = None
            elif 'known' in pdu['startTime']:
                self.start_time = pdu['startTime']['known']
            if 'undefined' in pdu['stopTime']:
                self.stop_time = None
            elif 'known' in pdu['stopTime']:
                self.stop_time = pdu['stopTime']['known']
            # else:
            # ToDo raise error

            pdu_return = RafProviderToUserPdu()['rafStartReturn']
            if self.factory.container.remote_peers[
                    self._initiator_id]['authentication_mode'] == 'ALL':
                pdu_return['performerCredentials']['used'] = make_credentials(
                    self.factory.container.local_id,
                    self.factory.container.local_password)
            else:
                pdu_return['performerCredentials']['unused'] = None
            pdu_return['invokeId'] = self._invoke_id
            '''
            if self._invoke_id in self._invoked_ids:
                pdu_return['result']['negativeResult']['common'] = 'duplicateInvokeId'
            '''
            # ToDo: pdu_return['result']['negative']['specific'] = 'unableToComply'
            # ToDo: pdu_return['result']['negative']['specific'] = 'invalidStartTime'
            # ToDo: pdu_return['result']['negative']['specific'] = 'invalidStopTime'
            # ToDo: pdu_return['result']['negative']['common'] = 'otherReason'
            if self.factory.container.si_config[
                    self._inst_id]['state'] is 'halted':
                pdu_return['result']['negativeResult'][
                    'specific'] = 'outOfService'
            elif self.factory.container.si_config[self._inst_id][
                    'delivery_mode'] == 'OFFLINE':  # ToDo: case sensitive?
                if 'undefined' in pdu['startTime'] or 'undefined' in pdu[
                        'stopTime']:
                    pdu_return['result']['negativeResult'][
                        'specific'] = 'missingTimeValue'
            elif str(pdu['requestedFrameQuality']) \
                    not in self.factory.container.si_config[self._inst_id]['permitted_frame_quality']:
                pdu_return['result']['negativeResult'][
                    'common'] = 'otherReason'
            elif self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == \
                    'ALL' and not check_invoke_credentials(self._invoker_credentials, self._initiator_id,
                                          str(self.factory.container.remote_peers[str(self._initiator_id)]['password'])):
                pdu_return['result']['negativeResult'][
                    'common'] = 'otherReason'
            else:
                pdu_return['result']['positiveResult'] = None
            self._send_pdu(pdu_return)
            if 'negativeResult' not in pdu_return['result']:
                self.factory.container.si_config[self._inst_id]['requested_frame_quality'] = \
                    str(pdu['requestedFrameQuality'])
                self.factory.container.si_config[
                    self._inst_id]['state'] = 'active'

                if self._wrapper is not None:
                    if self._wrapper['name'] == 'CCSDS-TM-SPP':
                        self.factory.container.data_endpoints[0].send_command(
                            'start-telemetry', [
                                'OBSERVATION_ID={}'.format(
                                    self._requested_observation),
                                'WRAPPER={}'.format(self._wrapper['name']),
                                'tm-length={}'.format(
                                    self._wrapper['args']['tm-length']),
                                'tm-has-fecf={}'.format(
                                    self._wrapper['args']['tm-has-fecf']),
                                'tm-is-idle={}'.format(
                                    self._wrapper['args']['tm-is-idle']),
                                'tm-version={}'.format(
                                    self._wrapper['args']['tm-version']),
                                'tm-spacecraft-id={}'.format(
                                    self._wrapper['args']['tm-spacecraft-id']),
                                'tm-virtual-channel-id={}'.format(
                                    self._wrapper['args']
                                    ['tm-virtual-channel-id']),
                                'tm-ocf-flag={}'.format(
                                    self._wrapper['args']['tm-ocf-flag']),
                                'tm-master-channel-frame-count={}'.format(
                                    self._wrapper['args']
                                    ['tm-master-channel-frame-count']),
                                'tm-virtual-channel-frame-count={}'.format(
                                    self._wrapper['args']
                                    ['tm-virtual-channel-frame-count']),
                                'tm-secondary-header-flag={}'.format(
                                    self._wrapper['args']
                                    ['tm-secondary-header-flag']),
                                'tm-sync-flag={}'.format(
                                    self._wrapper['args']['tm-sync-flag']),
                                'tm-packet-order-flag={}'.format(
                                    self._wrapper['args']
                                    ['tm-packet-order-flag']),
                                'tm-segment-length-id={}'.format(
                                    self._wrapper['args']
                                    ['tm-segment-length-id']),
                                'tm-first-header-pointer={}'.format(
                                    self._wrapper['args']
                                    ['tm-first-header-pointer']),
                                'tm-ocf={}'.format(
                                    self._wrapper['args']['tm-ocf']),
                                'spp-version={}'.format(
                                    self._wrapper['args']['spp-version']),
                                'spp-type={}'.format(
                                    self._wrapper['args']['spp-type']),
                                'spp-secondary-header-flag={}'.format(
                                    self._wrapper['args']
                                    ['spp-secondary-header-flag']),
                                'spp-apid={}'.format(
                                    self._wrapper['args']['spp-apid']),
                                'spp-sequence-flags={}'.format(
                                    self._wrapper['args']
                                    ['spp-sequence-flags']),
                                'spp-sequence-count-or-packet-name={}'.format(
                                    self._wrapper['args']
                                    ['spp-sequence-count-or-packet-name'])
                            ])
                    elif self._wrapper['name'] == 'OPS-SAT':
                        self.factory.container.data_endpoints[0].send_command(
                            'start-telemetry', [
                                'OBSERVATION_ID={}'.format(
                                    self._requested_observation),
                                'WRAPPER={}'.format(self._wrapper['name']),
                                'tm-length={}'.format(
                                    self._wrapper['args']['tm-length']),
                                'tm-has-fecf={}'.format(
                                    self._wrapper['args']['tm-has-fecf']),
                                'tm-is-idle={}'.format(
                                    self._wrapper['args']['tm-is-idle']),
                                'tm-version={}'.format(
                                    self._wrapper['args']['tm-version']),
                                'tm-spacecraft-id={}'.format(
                                    self._wrapper['args']['tm-spacecraft-id']),
                                'tm-virtual-channel-id={}'.format(
                                    self._wrapper['args']
                                    ['tm-virtual-channel-id']),
                                'tm-ocf-flag={}'.format(
                                    self._wrapper['args']['tm-ocf-flag']),
                                'tm-master-channel-frame-count={}'.format(
                                    self._wrapper['args']
                                    ['tm-master-channel-frame-count']),
                                'tm-virtual-channel-frame-count={}'.format(
                                    self._wrapper['args']
                                    ['tm-virtual-channel-frame-count']),
                                'tm-secondary-header-flag={}'.format(
                                    self._wrapper['args']
                                    ['tm-secondary-header-flag']),
                                'tm-sync-flag={}'.format(
                                    self._wrapper['args']['tm-sync-flag']),
                                'tm-packet-order-flag={}'.format(
                                    self._wrapper['args']
                                    ['tm-packet-order-flag']),
                                'tm-segment-length-id={}'.format(
                                    self._wrapper['args']
                                    ['tm-segment-length-id']),
                                'tm-first-header-pointer={}'.format(
                                    self._wrapper['args']
                                    ['tm-first-header-pointer']),
                                'tm-ocf={}'.format(
                                    self._wrapper['args']['tm-ocf'])
                            ])
                    else:
                        self.factory.container.data_endpoints[0].send_command(
                            'start-telemetry', [
                                'OBSERVATION_ID={}'.format(
                                    self._requested_observation),
                                'WRAPPER=None'
                            ])
                else:
                    self.factory.container.data_endpoints[0].send_command(
                        'start-telemetry', [
                            'OBSERVATION_ID={}'.format(
                                self._requested_observation), 'WRAPPER=None'
                        ])
Пример #9
0
 def _schedule_status_report_invocation_handler(self, pdu):
     logger.debug('Get Schedule Status Report Invocation received!')
     pdu = pdu['rafScheduleStatusReportInvocation']
     pdu_return = RafProviderToUserPdu()['rafScheduleStatusReportReturn']
     if 'used' in pdu['invokerCredentials']:
         self._invoker_credentials = pdu['invokerCredentials']['used']
         pdu_return['performerCredentials']['used'] = make_credentials(
             self.factory.container.local_id,
             self.factory.container.local_password)
     else:
         self._invoker_credentials = None
         pdu_return['performerCredentials']['unused'] = None
     # ToDo: pdu_return['result']['negativeResult']['common'] = 'duplicateInvokeId'
     pdu_return['invokeId'] = int(pdu['invokeId'])
     if self.factory.container.si_config[self._inst_id]['state'] not in {
             'ready', 'active'
     }:
         pdu_return['result']['negativeResult']['common'] = 'otherReason'
     elif self.factory.container.si_config[
             self._inst_id]['delivery_mode'] == 'OFFLINE':
         pdu_return['result']['negativeResult'][
             'specific'] = 'notSupportedInThisDeliveryMode'
     elif self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == \
             'ALL' and not check_invoke_credentials(self._invoker_credentials, self._initiator_id,
                                         str(self.factory.container.remote_peers[str(self._initiator_id)][
                                                 'password'])):
         pdu_return['result']['negativeResult']['common'] = 'otherReason'
     elif 'periodically' in pdu['reportRequestType']:
         if not (self.factory.container.min_reporting_cycle <= int(
                 pdu['reportRequestType']['periodically']) <=
                 self.factory.container.max_reporting_cycle):
             pdu_return['result']['negativeResult'][
                 'specific'] = 'invalidReportingCycle'
         else:
             if self._report_timer is None:
                 self._report_timer = reactor.callLater(
                     int(pdu['reportRequestType']['periodically']),
                     self._send_status_report)
                 self.factory.container.si_config[self._inst_id]['report_cycle'] = \
                     int(pdu['reportRequestType']['periodically'])
             else:
                 self.factory.container.si_config[self._inst_id]['report_cycle'] = \
                     int(pdu['reportRequestType']['periodically'])
                 self._report_timer.reset(
                     int(pdu['reportRequestType']['periodically']))
             pdu_return['result']['positiveResult'] = None
     elif 'stop' in pdu['reportRequestType']:
         if self._report_timer is None:
             pdu_return['result']['negativeResult'][
                 'specific'] = 'alreadyStopped'
         else:
             if (self._report_timer.called
                     == 1) or (self._report_timer.cancelled == 1):
                 self._report_timer = None
                 pdu_return['result']['negativeResult'][
                     'specific'] = 'alreadyStopped'
             else:
                 self._report_timer.cancel()
                 self._report_timer = None
                 pdu_return['result']['positiveResult'] = None
     elif 'immediately' in pdu['reportRequestType']:
         self._send_status_report()
         if self._report_timer is not None:
             if (self._report_timer.called
                     == 1) or (self._report_timer.cancelled == 1):
                 self._report_timer = None
             else:
                 self._report_timer.cancel()
                 self._report_timer = None
         pdu_return['result']['positiveResult'] = None
     else:
         raise Exception()
     self._send_pdu(pdu_return)
Пример #10
0
    def _get_parameter_invocation_handler(self, pdu):
        logger.debug('Get Parameter Invocation received!')
        pdu = pdu['rafGetParameterInvocation']
        pdu_return = RafProviderToUserPdu()['rafGetParameterReturn']

        if 'used' in pdu['invokerCredentials']:
            self._invoker_credentials = pdu['invokerCredentials']['used']
        else:
            self._invoker_credentials = None
            pdu_return['performerCredentials']['unused'] = None
        self._invoke_id = int(pdu['invokeId'])
        pdu_return['invokeId'] = self._invoke_id
        if self.factory.container.si_config[self._inst_id]['state'] not in {
                'ready', 'active'
        }:
            pdu_return['result']['negativeResult']['common'] = 'otherReason'
        # ToDo: pdu_return['result']['negative'] = 'duplicate Invoke-ID'
        elif str(pdu['rafParameter']) not in [
                n for n in RafParameterName().namedValues
        ]:
            pdu_return['result']['negativeResult'] = 'unknownParameter'
        elif self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == \
                'ALL' and not check_invoke_credentials(self._invoker_credentials, self._initiator_id,
                                            str(self.factory.container.remote_peers[str(self._initiator_id)][
                                                    'password'])):
            pdu_return['result']['negativeResult']['common'] = 'otherReason'
        else:
            if self.factory.container.remote_peers[
                    self._initiator_id]['authentication_mode'] == 'ALL':
                if check_invoke_credentials(
                        self._invoker_credentials, self._initiator_id,
                        str(self.factory.container.remote_peers[str(
                            self._initiator_id)]['password'])):
                    pdu_return['performerCredentials'][
                        'used'] = make_credentials(
                            self._initiator_id,
                            str(self.factory.container.remote_peers[str(
                                self._initiator_id)]['password']))
            raf_parameter = str(pdu['rafParameter'])
            if raf_parameter == 'bufferSize':
                pdu_return['result']['positiveResult']['parBufferSize']['parameterName'] = \
                    'bufferSize'
                pdu_return['result']['positiveResult']['parBufferSize']['parameterValue'] = \
                    self.factory.container.si_config[self._inst_id]['transfer_buffer_size']
            elif raf_parameter == 'deliveryMode':
                pdu_return['result']['positiveResult']['parDeliveryMode']['parameterName'] = \
                    'deliveryMode'
                if self.factory.container.si_config[
                        self._inst_id]['delivery_mode'] == 'TIMELY_ONLINE':
                    pdu_return['result']['positiveResult']['parDeliveryMode']['parameterValue'] = \
                        'rtnTimelyOnline'
                elif self.factory.container.si_config[
                        self._inst_id]['delivery_mode'] == 'COMPLETE_ONLINE':
                    pdu_return['result']['positiveResult']['parDeliveryMode']['parameterValue'] = \
                        'rtnCompleteOnline'
                elif self.factory.container.si_config[
                        self._inst_id]['delivery_mode'] == 'OFFLINE':
                    pdu_return['result']['positiveResult']['parDeliveryMode']['parameterValue'] = \
                        'rtnOffline'
            elif raf_parameter == 'latencyLimit':
                pdu_return['result']['positiveResult']['parLatencyLimit']['parameterName'] = \
                    'latencyLimit'
                if self.factory.container.si_config[
                        self._inst_id]['delivery_mode'] == 'OFFLINE':
                    pdu_return['result']['positiveResult']['parLatencyLimit']['parameterValue']['offline'] = \
                        None
                else:
                    pdu_return['result']['positiveResult']['parLatencyLimit']['parameterValue']['online'] = \
                        self.factory.container.si_config[self._inst_id]['latency_limit']
            elif raf_parameter == 'minReportingCycle':
                pdu_return['result']['positiveResult']['parMinReportingCycle']['parameterName'] = \
                    'minReportingCycle'
                pdu_return['result']['positiveResult']['parMinReportingCycle']['parameterValue'] = \
                    self.factory.container.min_reporting_cycle
            elif raf_parameter == 'permittedFrameQuality':
                pdu_return['result']['positiveResult']['parPermittedFrameQuality']['parameterName'] = \
                    'permittedFrameQuality'
                quality_set = PermittedFrameQualitySet()
                for pos, quality in enumerate(self.factory.container.si_config[
                        self._inst_id]['permitted_frame_quality']):
                    quality_set.setComponentByPosition(pos, quality)
                pdu_return['result']['positiveResult']['parPermittedFrameQuality']['parameterValue'] = \
                    quality_set
            elif raf_parameter == 'reportingCycle':
                pdu_return['result']['positiveResult']['parReportingCycle']['parameterName'] = \
                    'reportingCycle'
                if self.factory.container.si_config[
                        self._inst_id]['report_cycle'] is None:
                    pdu_return['result']['positiveResult']['parReportingCycle']['parameterValue']['periodicReportingOff'] = \
                        None
                else:
                    pdu_return['result']['positiveResult']['parReportingCycle']['parameterValue']['periodicReportingOn'] = \
                        self.factory.container.si_config[self._inst_id]['report_cycle']
            elif raf_parameter == 'requestedFrameQuality':
                pdu_return['result']['positiveResult']['parReqFrameQuality']['parameterName'] = \
                    'requestedFrameQuality'
                if self.factory.container.si_config[
                        self._inst_id]['state'] == 'ready':
                    pdu_return['result']['positiveResult']['parReqFrameQuality']['parameterValue'] = \
                        self.factory.container.si_config[self._inst_id]['permitted_frame_quality'][0]
                else:
                    pdu_return['result']['positiveResult']['parReqFrameQuality']['parameterValue'] = \
                        self.factory.container.si_config[self._inst_id]['requested_frame_quality']
            elif raf_parameter == 'returnTimeoutPeriod':
                pdu_return['result']['positiveResult']['parReturnTimeout']['parameterName'] = \
                    'returnTimeoutPeriod'
                pdu_return['result']['positiveResult']['parReturnTimeout']['parameterValue'] = \
                    self.factory.container.si_config[self._inst_id]['return_timeout_period']
        self._send_pdu(pdu_return)
Пример #11
0
    def _start_invocation_handler(self, pdu):
        logger.debug('Start Invocation received!')
        if self.factory.container.si_config[
                self._inst_id]['state'] is not 'ready':
            logger.error('Invalid state transition')
            self.peer_abort()
        else:
            pdu = pdu['rafStartInvocation']
            if 'used' in pdu['invokerCredentials']:
                self._invoker_credentials = pdu['invokerCredentials']['used']
            else:
                self._invoker_credentials = None
            self._invoke_id = int(pdu['invokeId'])
            if 'undefined' in pdu['startTime']:
                self.start_time = None
            elif 'known' in pdu['startTime']:
                self.start_time = pdu['startTime']['known']
            if 'undefined' in pdu['stopTime']:
                self.stop_time = None
            elif 'known' in pdu['stopTime']:
                self.stop_time = pdu['stopTime']['known']
            # else:
            # ToDo raise error

            pdu_return = RafProviderToUserPdu()['rafStartReturn']
            if self.factory.container.remote_peers[
                    self._initiator_id]['authentication_mode'] == 'ALL':
                pdu_return['performerCredentials']['used'] = make_credentials(
                    self.factory.container.local_id,
                    self.factory.container.local_password)
            else:
                pdu_return['performerCredentials']['unused'] = None
            pdu_return['invokeId'] = self._invoke_id
            '''
            if self._invoke_id in self._invoked_ids:
                pdu_return['result']['negativeResult']['common'] = 'duplicateInvokeId'
            '''
            # ToDo: pdu_return['result']['negative']['specific'] = 'unableToComply'
            # ToDo: pdu_return['result']['negative']['specific'] = 'invalidStartTime'
            # ToDo: pdu_return['result']['negative']['specific'] = 'invalidStopTime'
            # ToDo: pdu_return['result']['negative']['common'] = 'otherReason'
            if self.factory.container.si_config[
                    self._inst_id]['state'] is 'halted':
                pdu_return['result']['negativeResult'][
                    'specific'] = 'outOfService'
            elif self.factory.container.si_config[self._inst_id][
                    'delivery_mode'] == 'OFFLINE':  # ToDo: case sensitive?
                if 'undefined' in pdu['startTime'] or 'undefined' in pdu[
                        'stopTime']:
                    pdu_return['result']['negativeResult'][
                        'specific'] = 'missingTimeValue'
            elif str(pdu['requestedFrameQuality']) \
                    not in self.factory.container.si_config[self._inst_id]['permitted_frame_quality']:
                pdu_return['result']['negativeResult'][
                    'common'] = 'otherReason'
            elif self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == \
                    'ALL' and not check_invoke_credentials(self._invoker_credentials, self._initiator_id,
                                          str(self.factory.container.remote_peers[str(self._initiator_id)]['password'])):
                pdu_return['result']['negativeResult'][
                    'common'] = 'otherReason'
            else:
                pdu_return['result']['positiveResult'] = None
            self._send_pdu(pdu_return)
            if 'negativeResult' not in pdu_return['result']:
                self.factory.container.si_config[self._inst_id]['requested_frame_quality'] = \
                    str(pdu['requestedFrameQuality'])
                self.factory.container.si_config[
                    self._inst_id]['state'] = 'active'
    def _bind_invocation_handler(self, pdu):
        logger.debug('Bind Invocation received!')
        if 'used' in pdu['rafBindInvocation']['invokerCredentials']:
            self._invoker_credentials = pdu['rafBindInvocation'][
                'invokerCredentials']['used']
        else:
            self._invoker_credentials = None
        self._responder_port = str(
            pdu['rafBindInvocation']['responderPortIdentifier'])
        if str(pdu['rafBindInvocation']['serviceType']) == 'rtnAllFrames':
            self._service_type = str(pdu['rafBindInvocation']['serviceType'])
            self._coding = SleCoding(decode_spec=RafUserToProviderPdu())
            self._version = int(pdu['rafBindInvocation']['versionNumber'])
            pdu_return = RafProviderToUserPdu()['rafBindReturn']
        else:
            raise Exception('Not Implemented')
            # ToDo implement more service types

        pdu_return['responderIdentifier'] = self.factory.container.local_id
        self._initiator_id = pdu['rafBindInvocation']['initiatorIdentifier']
        ###
        # Query the API to get the registered Users
        peers_database = {
            "sle-users": [{
                "INITIATOR_AUTH":
                "NONE",
                "INITIATOR_ID":
                "ESA",
                "INITIATOR_PASS":
                "******",
                "SATELLITES": [{
                    "id": 44878,
                    "wrapper": {
                        "args": {
                            "tm-first-header-pointer": "00000000000",
                            "tm-has-fecf": True,
                            "tm-is-idle": False,
                            "tm-length": 1115,
                            "tm-master-channel-frame-count": 0,
                            "tm-ocf": "0x01000000",
                            "tm-ocf-flag": False,
                            "tm-packet-order-flag": False,
                            "tm-secondary-header-flag": False,
                            "tm-segment-length-id": 3,
                            "tm-spacecraft-id": 810,
                            "tm-sync-flag": False,
                            "tm-version": 0,
                            "tm-virtual-channel-frame-count": 0,
                            "tm-virtual-channel-id": 0
                        },
                        "id": 1,
                        "name": "OPS-SAT"
                    }
                }],
                "id":
                1
            }, {
                "INITIATOR_AUTH": "NONE",
                "INITIATOR_ID": "FOX",
                "INITIATOR_PASS": "",
                "SATELLITES": [{
                    "id": 43017,
                    "wrapper": None
                }],
                "id": 2
            }, {
                "INITIATOR_AUTH":
                "NONE",
                "INITIATOR_ID":
                "FOXB",
                "INITIATOR_PASS":
                "",
                "SATELLITES": [{
                    "id": 43017,
                    "wrapper": {
                        "args": {
                            "spp-apid": 1,
                            "spp-secondary-header-flag": False,
                            "spp-sequence-count-or-packet-name": 0,
                            "spp-sequence-flags": 3,
                            "spp-type": 0,
                            "spp-version": 0,
                            "tm-first-header-pointer": "00000000000",
                            "tm-has-fecf": True,
                            "tm-is-idle": False,
                            "tm-length": 1115,
                            "tm-master-channel-frame-count": 0,
                            "tm-ocf": "0x01000000",
                            "tm-ocf-flag": False,
                            "tm-packet-order-flag": False,
                            "tm-secondary-header-flag": False,
                            "tm-segment-length-id": 3,
                            "tm-spacecraft-id": 810,
                            "tm-sync-flag": False,
                            "tm-version": 0,
                            "tm-virtual-channel-frame-count": 0,
                            "tm-virtual-channel-id": 0
                        },
                        "id": 1,
                        "name": "CCSDS-TM-SPP"
                    }
                }],
                "id":
                3
            }]
        }
        peers = peers_database['sle-users']
        for peer in peers:
            remote_peer = {
                str(peer['INITIATOR_ID']): {
                    'authentication_mode': str(peer['INITIATOR_AUTH']),
                    'password': str(peer['INITIATOR_PASS']),
                    'satellites': peer['SATELLITES']
                }
            }
            self.factory.container.remote_peers.update(remote_peer)
        ###
        if self._initiator_id not in self.factory.container.remote_peers:
            pdu_return['result']['negative'] = 'accessDenied'
        elif self._service_type not in self.factory.container.server_types:
            pdu_return['result']['negative'] = 'serviceTypeNotSupported'
        elif self._version not in self.factory.container.server_types[
                self._service_type]:
            pdu_return['result']['negative'] = 'versionNotSupported'

        if 'negative' not in pdu_return['result']:
            self._inst_id = ''
            ctr = 0
            for i in pdu['rafBindInvocation']['serviceInstanceIdentifier']:
                self._inst_id += sii_dict[str(i[0]['identifier'])] + '=' + str(
                    i[0]['siAttributeValue'])
                if ctr == 1:
                    self._requested_observation = str(
                        i[0]['siAttributeValue']).split('-')[-1]
                if i != pdu['rafBindInvocation']['serviceInstanceIdentifier'][
                        -1]:
                    self._inst_id += '.'
                ctr += 1
            ###
            # Query the API for the requested observation and check if it exists
            observation_request = requests.get(
                str(os.getenv('SATNOGS_NETWORK_API_EXTERNAL')) +
                '/observations',
                params={"id": self._requested_observation})
            observations = observation_request.json()
            if observations != []:
                observation = observations[0]
                # ToDo: Start and stop time conversation
                service_instance = {
                    'sagr=1.spack=ID-{}-PASS-{}.rsl-fg=1.raf=onlt1'.format(
                        self._initiator_id, observation['id']): {
                        'start_time':
                        None,
                        'stop_time':
                        None,
                        'initiator_id':
                        str(self._initiator_id),
                        'responder_id':
                        self.factory.container.local_id,
                        'return_timeout_period':
                        int(os.getenv('SLE_PROVIDER_RETURN_TIMEOUT_PERIOD',
                                      15)),
                        'delivery_mode':
                        'TIMELY_ONLINE',
                        'initiator':
                        'USER',
                        'permitted_frame_quality':
                        ['allFrames', 'erredFramesOnly', 'goodFramesOnly'],
                        'latency_limit':
                        int(os.getenv('SLE_PROVIDER_LATENCY_LIMIT', 9)),
                        'transfer_buffer_size':
                        int(os.getenv('SLE_PROVIDER_TRANSFER_BUFFER_SIZE',
                                      20)),
                        'report_cycle':
                        None,
                        'requested_frame_quality':
                        'allFrames',
                        'state':
                        'unbound'
                    }
                }
                self.factory.container.si_config.update(service_instance)

            satellite_accessible = False
            for sat in self.factory.container.remote_peers[
                    self._initiator_id]['satellites']:
                if sat['id'] == observation['norad_cat_id']:
                    satellite_accessible = True
                    self._wrapper = sat['wrapper']
                    break

            if self._inst_id not in self.factory.container.si_config:
                pdu_return['result']['negative'] = 'noSuchServiceInstance'
            elif self.factory.container.si_config[
                    self._inst_id]['state'] != 'unbound':
                pdu_return['result']['negative'] = 'alreadyBound'
            elif self.factory.container.si_config[
                    self._inst_id]['state'] == 'halted':
                pdu_return['result']['negative'] = 'outOfService'
            elif not satellite_accessible:
                pdu_return['result'][
                    'negative'] = 'siNotAccessibleToThisInitiator'
            # ToDo out of provisioning period
            else:
                # ToDo move upwards otherwise unreachable
                if self._service_type is 'rtnAllFrames':
                    if '.raf=' not in self._inst_id:
                        pdu_return['result'][
                            'negative'] = 'inconsistentServiceType'
        if self._initiator_id in self.factory.container.remote_peers:
            if self.factory.container.remote_peers[
                    self._initiator_id]['authentication_mode'] == 'NONE':
                if 'used' in pdu['rafBindInvocation']['invokerCredentials']:
                    logger.info(
                        "Disconnecting, authentication modes do not match")
                    self.disconnect()
                pdu_return['performerCredentials']['unused'] = None
            elif (('used' in pdu['rafBindInvocation']['invokerCredentials'])
                    and (self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == 'NONE')) \
                    or ('used' not in pdu['rafBindInvocation']['invokerCredentials']
                        and ((self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == 'BIND')
                        or (self.factory.container.remote_peers[self._initiator_id]['authentication_mode'] == 'ALL'))):
                logger.info("Disconnecting, authentication modes do not match")
                self.disconnect()
                return
            else:
                pdu_return['performerCredentials']['used'] = make_credentials(
                    self.factory.container.local_id,
                    self.factory.container.local_password)
        else:
            pdu_return['performerCredentials']['unused'] = None

        if 'negative' not in pdu_return['result']:
            if self.factory.container.remote_peers[
                    self._initiator_id]['authentication_mode'] != 'NONE':
                if check_invoke_credentials(
                        self._invoker_credentials, self._initiator_id,
                        str(self.factory.container.remote_peers[str(
                            self._initiator_id)]['password'])):
                    pdu_return['result']['positive'] = self._version
                    self.factory.container.si_config[
                        self._inst_id]['state'] = 'ready'
                else:
                    pdu_return['result']['negative'] = 'accessDenied'
                    self._inst_id = None
                    logger.error('Bind error {}'.format(
                        str(pdu_return['result']['negative'])))
            else:
                pdu_return['result']['positive'] = self._version
                self.factory.container.si_config[
                    self._inst_id]['state'] = 'ready'
        else:
            self._inst_id = None
            logger.error('Bind error {}'.format(
                str(pdu_return['result']['negative'])))
        self._send_pdu(pdu_return)

        if 'negative' not in pdu_return['result']:
            if self._service_type == 'rtnAllFrames':
                from .rafStatelessProtocol import RafStatelessProtocol
                self.__class__ = RafStatelessProtocol
                self._initialise()
Пример #13
0
    def _transfer_data_invocation_handler(self, pdu):
        logger.debug('Transfer Data Invocation received!')
        if self.factory.container.si_config[
                self._inst_id]['state'] is not 'active':
            logger.error('Invalid state transition')
            self.peer_abort()
        else:
            pdu = pdu['cltuTransferDataInvocation']
            pdu_return = CltuProviderToUserPdu()['cltuTransferDataReturn']
            if 'used' in pdu['invokerCredentials']:
                self._invoker_credentials = pdu['invokerCredentials']['used']
                if check_invoke_credentials(
                        self._invoker_credentials, self._initiator_id,
                        str(self.factory.container.remote_peers[str(
                            self._initiator_id)]['password'])):
                    pdu_return['performerCredentials'][
                        'used'] = make_credentials(
                            self.factory.container.local_id,
                            str(self.factory.container.remote_peers[str(
                                self._initiator_id)]['password']))
            else:
                pdu_return['performerCredentials']['unused'] = None
                self._invoker_credentials = None
            self._invoke_id = int(pdu['invokeId'])
            pdu_return['invokeId'] = self._invoke_id

            self.cltu_identification = int(pdu['cltuIdentification'])
            # ToDo: Minimum time in milliseconds between radiation of this and next CLTU
            self.delay_time = int(pdu['delayTime'])

            if 'undefined' in pdu['earliestTransmissionTime']:
                self.earliest_transmission_time = None
            elif 'known' in pdu['earliestTransmissionTime']:
                # ToDo: Implement
                raise NotImplementedError
                # self.earliest_transmission_time = pdu['earliestTransmissionTime']['known']
            if 'undefined' in pdu['latestTransmissionTime']:
                self.latest_transmission_time = None
            elif 'known' in pdu['latestTransmissionTime']:
                # ToDo: Implement
                raise NotImplementedError
                # self.latest_transmission_time = pdu['latestTransmissionTime']['known']

            if str(pdu['slduRadiationNotification']
                   ) == 'doNotProduceNotification':
                pass
            else:
                # ToDo: Implement produceNotification mechanism
                raise NotImplementedError
            self._number_of_cltus_received += 1
            self.last_radiation_start_time = str(dt.datetime.utcnow(
            ))  # ToDo: How to find out when actually started?
            str_time = dt.datetime.strptime(self.last_radiation_start_time,
                                            '%Y-%m-%d %H:%M:%S.%f')
            time_days = (str_time - dt.datetime(1958, 1, 1)).days
            time_ms = (str_time - dt.datetime(str_time.year, str_time.month, str_time.day)).seconds \
                      * 1000 + ((str_time - dt.datetime(str_time.year, str_time.month,
                                                        str_time.day)).microseconds // 1000)
            time_micro = ((str_time - dt.datetime(
                str_time.year, str_time.month, str_time.day)).microseconds %
                          1000)
            self.last_radiation_start_time = struct.pack(
                '!HIH', time_days, time_ms, time_micro)
            self._cltu_last_processed = self.cltu_identification  # ToDo: Get feedback from data_endpoint if actually radiated

            self.factory.container.data_endpoints[0].send_command(
                'send-telecommand', [pdu['cltuData']._value.hex()])

            self._number_of_cltus_processed += 1
            self._number_of_cltus_radiated += 1  # ToDo: Get feedback from data_endpoint if actually radiated
            self.last_radiation_stop_time = str(
                dt.datetime.utcnow())  # ToDo: How to find out when radiated?
            str_time = dt.datetime.strptime(self.last_radiation_stop_time,
                                            '%Y-%m-%d %H:%M:%S.%f')
            time_days = (str_time - dt.datetime(1958, 1, 1)).days
            time_ms = (str_time - dt.datetime(str_time.year, str_time.month, str_time.day)).seconds \
                      * 1000 + ((str_time - dt.datetime(str_time.year, str_time.month,
                                                        str_time.day)).microseconds // 1000)
            time_micro = ((str_time - dt.datetime(
                str_time.year, str_time.month, str_time.day)).microseconds %
                          1000)
            self.last_radiation_stop_time = struct.pack(
                '!HIH', time_days, time_ms, time_micro)
            self._cltu_last_ok = self.cltu_identification  # ToDo: Get feedback from data_endpoint if actually radiated

            # ToDo: implement logic and different counting for return cltu identification if rejected
            pdu_return['cltuIdentification'] = self.cltu_identification + 1
            pdu_return['cltuBufferAvailable'] = self._cltu_buffer_availiable
            # ToDo: Negative result
            pdu_return['result']['positiveResult'] = None
            self._send_pdu(pdu_return)
Пример #14
0
    def _bind_invocation_handler(self, pdu):
        logger.debug('Bind Invocation received!')
        if 'used' in pdu['rafBindInvocation']['invokerCredentials']:
            self._invoker_credentials = pdu['rafBindInvocation'][
                'invokerCredentials']['used']
        else:
            self._invoker_credentials = None
        self._responder_port = str(
            pdu['rafBindInvocation']['responderPortIdentifier'])
        if str(pdu['rafBindInvocation']['serviceType']) == 'rtnAllFrames':
            self._service_type = str(pdu['rafBindInvocation']['serviceType'])
            self._coding = SleCoding(decode_spec=RafUserToProviderPdu())
            self._version = int(pdu['rafBindInvocation']['versionNumber'])
            pdu_return = RafProviderToUserPdu()['rafBindReturn']
        elif str(pdu['rafBindInvocation']['serviceType']) == 'fwdCltu':
            self._service_type = str(pdu['rafBindInvocation']['serviceType'])
            self._coding = SleCoding(decode_spec=CltuUserToProviderPdu())
            self._version = int(pdu['rafBindInvocation']['versionNumber'])
            pdu_return = CltuProviderToUserPdu()['cltuBindReturn']
        else:
            raise Exception('Not Implemented')
            # ToDo implement more service types

        pdu_return['responderIdentifier'] = self.factory.container.local_id

        self._initiator_id = pdu['rafBindInvocation']['initiatorIdentifier']

        if self._initiator_id not in self.factory.container.remote_peers:
            pdu_return['result']['negative'] = 'accessDenied'
        elif self._service_type not in self.factory.container.server_types:
            pdu_return['result']['negative'] = 'serviceTypeNotSupported'
        elif self._version not in self.factory.container.server_types[
                self._service_type]:
            pdu_return['result']['negative'] = 'versionNotSupported'

        if 'negative' not in pdu_return['result']:
            self._inst_id = ''
            for i in pdu['rafBindInvocation']['serviceInstanceIdentifier']:
                self._inst_id += sii_dict[str(i[0]['identifier'])] + '=' + str(
                    i[0]['siAttributeValue'])
                if i != pdu['rafBindInvocation']['serviceInstanceIdentifier'][
                        -1]:
                    self._inst_id += '.'
            if self._inst_id not in self.factory.container.si_config:
                pdu_return['result']['negative'] = 'noSuchServiceInstance'
            elif self.factory.container.si_config[
                    self._inst_id]['state'] != 'unbound':
                pdu_return['result']['negative'] = 'alreadyBound'
            elif self.factory.container.si_config[
                    self._inst_id]['state'] == 'halted':
                pdu_return['result']['negative'] = 'outOfService'
            elif self.factory.container.si_config[
                    self._inst_id]['initiator_id'] != self._initiator_id:
                pdu_return['result'][
                    'negative'] = 'siNotAccessibleToThisInitiator'
            # ToDo out of provisioning period
            else:
                # ToDo move upwards otherwise unreachable
                if self._service_type is 'rtnAllFrames':
                    if '.raf=' not in self._inst_id:
                        pdu_return['result'][
                            'negative'] = 'inconsistentServiceType'
                elif self._service_type is 'fwdCltu':
                    if '.cltu=' not in self._inst_id:
                        pdu_return['result'][
                            'negative'] = 'inconsistentServiceType'

        if self.factory.container.remote_peers[
                self._initiator_id]['authentication_mode'] == 'NONE':
            pdu_return['performerCredentials']['unused'] = None
        else:
            pdu_return['performerCredentials']['used'] = make_credentials(
                self.factory.container.local_id,
                self.factory.container.local_password)
        if 'negative' not in pdu_return['result']:
            if self.factory.container.remote_peers[
                    self._initiator_id]['authentication_mode'] != 'NONE':
                if check_invoke_credentials(
                        self._invoker_credentials, self._initiator_id,
                        str(self.factory.container.remote_peers[str(
                            self._initiator_id)]['password'])):
                    pdu_return['result']['positive'] = self._version
                    self.factory.container.si_config[
                        self._inst_id]['state'] = 'ready'
                else:
                    pdu_return['result']['negative'] = 'accessDenied'
                    self._inst_id = None
                    logger.error('Bind error {}'.format(
                        str(pdu_return['result']['negative'])))
            else:
                pdu_return['result']['positive'] = self._version
                self.factory.container.si_config[
                    self._inst_id]['state'] = 'ready'
        else:
            self._inst_id = None
            logger.error('Bind error {}'.format(
                str(pdu_return['result']['negative'])))
        self._send_pdu(pdu_return)

        if 'negative' not in pdu_return['result']:
            if self._service_type == 'rtnAllFrames':
                from .rafProtocol import RafProtocol
                self.__class__ = RafProtocol
                self._initialise()
            elif self._service_type == 'fwdCltu':
                from .cltuProtocol import CltuProtocol
                self.__class__ = CltuProtocol
                self._initialise()