def test_add_range():
    print('Test add_range()')
    port_manager = PortManager()
    port_manager.add(first_hundred, 2)

    print(len(port_manager.rule_store) == 100)
    print(port_manager.rule_store[0] == {2})
    print(port_manager.rule_store[99] == {2})
def test_get_rules():
    print('Test get_rules()')
    port_manager = PortManager()
    port_manager.add(first_hundred, 3)
    port_manager.add(zero, 0)

    print(port_manager.get_rules('100') == set())
    print(port_manager.get_rules('0') == {0, 3})
Exemple #3
0
    def __init__(self, w=None):

        # Ports, pins, and services initialization
        # self.__pin_mode = [None]*(self.MAX_NUM_DIGITAL_PINS + self.MAX_NUM_ANALOG_PINS)
        self.__services = {}
        self.__port_map = PortManager()

        # constructor also work without writer parameter
        if w is not None:
            self.__out = w
            if self.DEBUG:
                sys.stdout.write('DEBUG: Constructor, writer supplied\n')

        if self.DEBUG:
            sys.stdout.write('DEBUG: End of constructor: arrays and maps created\n')
def test_add_single():
    print('Test add_single()')
    port_manager = PortManager()
    port_manager.add(zero, 0)
    port_manager.add(hundred, 1)
    port_manager.add(zero, 2)

    print(port_manager.rule_store[0] == {0, 2})
    print(port_manager.rule_store[99] == {1})
    print(len(port_manager.rule_store) == 2)
Exemple #5
0
 def __init__(self, rule_file):
     self.rule_file = rule_file
     self.rule_managers = {
         DIRECTION: SimpleManager(),
         PROTOCOL: SimpleManager(),
         PORT: PortManager(),
         IP_ADDRESS: IpAddressManager()
     }
     self.preprocessing()
Exemple #6
0
 def _do_pwncat(self):
     port = PortManager.get_open_port()
     subprocess.Popen([
         'tmux', 'new-window', '-n',
         f'pc:{self.selected_instance.username}', f'pwncat -lp {port}'
     ],
                      stdin=subprocess.DEVNULL,
                      stdout=subprocess.DEVNULL,
                      stderr=subprocess.DEVNULL)
     InstanceManager.messages_to_send.put(
         (self.selected_instance,
          Message(Message.OPEN_SHELL_CLASSIC, str(port))))
    def __init__(self, w=None):

        # Ports, pins, and services initialization
        # self.__pin_mode = [None]*(self.MAX_NUM_DIGITAL_PINS + self.MAX_NUM_ANALOG_PINS)
        self.__services = {}
        self.__port_map = PortManager()

        # constructor also work without writer parameter
        if w is not None:
            self.__out = w
            if self.DEBUG:
                sys.stdout.write('DEBUG: Constructor, writer supplied\n')

        if self.DEBUG:
            sys.stdout.write('DEBUG: End of constructor: arrays and maps created\n')
Exemple #8
0
class AsipClient:

    # Constants inherited from Java client version
    # TODO: implement emulation of constant through dedicated file / function

    # ************   BEGIN CONSTANTS DEFINITION ****************
    DEBUG = False  # Do you want me to print verbose debug information?

    # Low-level tags for I/O service:
    IO_SERVICE = 'I'  # tag indicating message is for I/O service
    PIN_MODE = 'P'  # i/o request  to Arduino to set pin mode
    DIGITAL_WRITE = 'd'  # i/o request  to Arduino is digitalWrite
    ANALOG_WRITE = 'a'  # i/o request to Arduino is analogWrite
    ANALOG_DATA_REQUEST = 'A'  # i/o request to Arduino to set Autoreport to a certain value in ms
    PORT_DATA = 'd'  # i/o event from Arduino is digital port data
    ANALOG_VALUE = 'a'  # i/o event from Arduino is value of analog pin
    PORT_MAPPING = 'M'  # i/o event from Arduino is port mapping to pins
    GET_PIN_MODES = 'p'  # gets a list of pin modes
    GET_PIN_SERVICES_LIST = 's'  # gets a list of pins indicating registered service
    # tag_GET_SERVICES_NAMES    = 'n' # gets a list of service tags/name pairs
    GET_PIN_CAPABILITIES = 'c'  # gets a bitfield array indicating pin capabilities

    #tag for system messages:
    SYSTEM_GET_INFO = '?'  # Get version and hardware info
    RESTART_REQUEST = 'R'  # disables all autoevents and attempts to restart all services

    # Pin modes (these are public)
    INPUT = 1  # defined in Arduino.h
    INPUT_PULLUP = 2  # defined in Arduino.h
    OUTPUT = 3  # defined in Arduino.h
    ANALOG = 4  # analog pin in analogInput mode
    PWM = 5  # digital pin in PWM output mode

    EVENT_HANDLER = '@'  # Standard incoming message
    SYSTEM_MSG_HEADER = '#'  # incoming is a system message
    ERROR_MESSAGE_HEADER = '~'  # Incoming message: error report
    DEBUG_MESSAGE_HEADER = '!'  # A debug message from the board (can be ignored, probably)

    # ************   END CONSTANTS DEFINITION ****************

    # ************   BEGIN PRIVATE FIELDS DEFINITION ****************

    # __digital_input_pins = []
    # __analog_input_pins = []
    # __pin_mode = []  # FIXME: do we need this at all?

    # PortManager object
    __port_map = None

    # A map from service IDs to actual implementations.
    # FIXME: there could be more than one service with the same ID!
    # (two servos, two distance sensors, etc).
    # use of the dict for python for hashmap
    __services = None

    # The output channel (where we write messages). This should typically be a serial port, but could be anything else.
    # out = AsipWriter()
    __out = None

    __AsipVersionOk = False  # flag to indicate that a valid version message has been received

    # ************   END PRIVATE FIELDS DEFINITION ****************

    #  A constructor taking the writer as parameter.
    def __init__(self, w=None):

        # Ports, pins, and services initialization
        # self.__pin_mode = [None]*(self.MAX_NUM_DIGITAL_PINS + self.MAX_NUM_ANALOG_PINS)
        self.__services = {}
        self.__port_map = PortManager()

        # constructor also work without writer parameter
        if w is not None:
            self.__out = w
            if self.DEBUG:
                sys.stdout.write('DEBUG: Constructor, writer supplied\n')

        if self.DEBUG:
            sys.stdout.write(
                'DEBUG: End of constructor: arrays and maps created\n')

    # ************ BEGIN PUBLIC METHODS *************

    # returns the port_map object (port_manager)
    def request_port_map(self):
        return self.__port_map

    # This method processes an input received on the serial port.
    # See protocol description for more detailed information.
    def process_input(self, input_str):
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: received input in process_input is {}\n".format(
                    input_str))
        if input_str[0] == self.EVENT_HANDLER:
            self.__handle_input_event(input_str)
        elif input_str[0] == self.ERROR_MESSAGE_HEADER:
            self.__handle_input_error(input_str)
        elif input_str[0] == self.DEBUG_MESSAGE_HEADER:
            self.__handle_debug_event(input_str)
        else:
            # FIXME: better error handling required! (raise exception) ?
            if self.DEBUG:
                sys.stdout.write(
                    "DEBUG: Strange character received at position 0: {}\n".
                    format(input_str))

    # method to request ASIP system info
    def request_info(self):
        self.__out.write("{},{}\n".format(self.SYSTEM_MSG_HEADER,
                                          self.SYSTEM_GET_INFO))
        if self.DEBUG:
            sys.stdout.write("DEBUG: Requesting info {},{}\n".format(
                self.SYSTEM_MSG_HEADER, self.SYSTEM_GET_INFO))

    # A method to request the mapping between ports and pins.
    # See process_port_data and process_pin_mapping for additional details on the actual mapping.
    def request_port_mapping(self):
        self.__out.write("{},{}\n".format(self.IO_SERVICE, self.PORT_MAPPING))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Requesting port mapping with {},{}\n".format(
                    self.IO_SERVICE, self.PORT_MAPPING))

    def digital_read(self, pin):
        # FIXME: should add error checking here
        return self.__port_map.digital_read(pin)

    def analog_read(self, pin):
        # FIXME: should add error checking here
        return self.__port_map.analog_read(pin)

    def set_pin_mode(self, pin, mode):
        self.__out.write("{},{},{},{}\n".format(self.IO_SERVICE, self.PIN_MODE,
                                                pin, mode))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting pin mode with {},{},{},{}\n".format(
                    self.IO_SERVICE, self.PIN_MODE, pin, mode))

    # A method to write to a digital pin
    def digital_write(self, pin, value):
        self.__out.write("{},{},{},{}\n".format(self.IO_SERVICE,
                                                self.DIGITAL_WRITE, pin,
                                                value))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting digital pin with {},{},{},{}\n".format(
                    self.IO_SERVICE, self.DIGITAL_WRITE, pin, value))

    # A method to write to an analog pin
    def analog_write(self, pin, value):
        self.__out.write("{},{},{},{}\n".format(self.IO_SERVICE,
                                                self.ANALOG_WRITE, pin, value))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting analog pin with {},{},{},{}\n".format(
                    self.IO_SERVICE, self.DIGITAL_WRITE, pin, value))

    # A method to set the autoreport interval (in ms)
    def set_auto_report_interval(self, interval):
        self.__out.write("{},{},{}\n".format(self.IO_SERVICE,
                                             self.ANALOG_DATA_REQUEST,
                                             interval))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting autoreport interval {},{},{}\n".format(
                    self.IO_SERVICE, self.ANALOG_DATA_REQUEST, interval))

    # It is possible to add a service at run-time:
    def add_service(self, service_id, asip_service):
        # If there is already a service with the same ID, we add this new one to the list:
        if service_id in self.__services:
            self.__services[service_id].append(asip_service)
            #self.__services[service_id] = asip_service
        # otherwise, we create a new list, a new key for the dictionary and associate the list to that key
        else:
            new_list = [asip_service]
            self.__services.update({service_id: new_list})

    # FIXME: maybe with python the following method is unuseful (Does the previous do the same?)
    # It is possible to add a list of services at run-time:
    def add_services(self, service_id, asip_ser_list):
        # we create a new key for the dictionary and associate the list to that key
        self.__services.update({service_id: asip_ser_list})

    # Just return the list of services
    def get_services(self):
        return self.__services

    # I'm not sure we want this public... FIXME?
    def get_digital_pins(self):
        return self.__port_map.get_digital_pins()

    # Getter and Setter for output channel
    def get_asip_writer(self):
        return self.__out

    def set_asip_writer(self, w):
        self.__out = w

    def isVersionOk(self):
        return self.__AsipVersionOk

    # ************ END PUBLIC METHODS *************

    # ************ BEGIN PRIVATE METHODS *************

    # A method to do what is says on the tin...
    def __handle_input_event(self, input_str):
        #print("mm: received message {}\n".format(input_str))
        if self.DEBUG:
            sys.stdout.write("DEBUG: received message {}\n".format(input_str))

        if input_str[1] == self.IO_SERVICE:
            # Digital pins (in port)

            # the port data event is something like: @I,P,4,F
            # this message says the data on port 4 has a value of F
            if input_str[3] == self.PORT_DATA:
                self.__port_map.process_port_data(input_str)
            elif input_str[3] == self.PORT_MAPPING:
                self.__port_map.process_pin_mapping(input_str)
            elif input_str[3] == self.ANALOG_VALUE:
                self.__port_map.process_analog_data(input_str)

            # TODO: implement missing messages!
            else:
                if self.DEBUG:
                    sys.stdout.write(
                        "DEBUG: Service not recognised in position 3 for I/O service: {}\n"
                        .format(input_str))
            # end of IO_SERVICE

        elif input_str[1] == self.SYSTEM_MSG_HEADER:
            if input_str[3] == self.SYSTEM_GET_INFO:
                field = input_str[5:].split(',')  #extract info fields
                info = 'ASIP version %s.%s running on %s using sketch: %s\n' % (
                    field[0], field[1], field[2], field[4])
                self.__AsipVersionOk = True  #TODO - check that the major version (field[0]) is supported by this client
                print(info)

        elif input_str[1] in self.__services.keys():
            # Is this one of the services we know? If this is the case, we call it and we process the input
            # I want a map function here!! For the moment we use a for loop...
            for s in self.__services[input_str[1]]:
                s.process_response(input_str)
                if self.DEBUG:
                    sys.stdout.write(
                        "DEBUG: calling process response for key {} and input {}\n"
                        .format(s, input))
        else:
            # We don't know what to do with it.
            if self.DEBUG:
                sys.stdout.write(
                    "DEBUG: Event not recognised at position 1: {}\n".format(
                        input_str))

    # To handle a message starting with an error header (this is a form of error reporting from Arduino)
    def __handle_input_error(self, input_str):
        # FIXME: improve error handling
        print("Error message received: {}\n".format(input_str))

    # For the moment we just report board's debug messages on screen
    # FIXME: do something smarter?
    def __handle_debug_event(self, input_str):
        print("dbg msg: {}\n".format(input_str))
class AsipClient:

    # Constants inherited from Java client version
    # TODO: implement emulation of constant through dedicated file / function

    # ************   BEGIN CONSTANTS DEFINITION ****************
    DEBUG = False  # Do you want me to print verbose debug information?

    # Low-level tags for I/O service:
    IO_SERVICE = 'I'  # tag indicating message is for I/O service
    PIN_MODE = 'P'  # i/o request  to Arduino to set pin mode
    DIGITAL_WRITE = 'd'  # i/o request  to Arduino is digitalWrite
    ANALOG_WRITE = 'a'  # i/o request to Arduino is analogWrite
    ANALOG_DATA_REQUEST = 'A'  # i/o request to Arduino to set Autoreport to a certain value in ms
    PORT_DATA = 'd'  # i/o event from Arduino is digital port data
    ANALOG_VALUE = 'a'  # i/o event from Arduino is value of analog pin
    PORT_MAPPING = 'M'  # i/o event from Arduino is port mapping to pins
    GET_PIN_MODES = 'p'  # gets a list of pin modes
    GET_PIN_SERVICES_LIST = 's'  # gets a list of pins indicating registered service
    # tag_GET_SERVICES_NAMES    = 'n' # gets a list of service tags/name pairs
    GET_PIN_CAPABILITIES = 'c'  # gets a bitfield array indicating pin capabilities
    
    #tag for system messages:
    SYSTEM_GET_INFO = '?' # Get version and hardware info
    RESTART_REQUEST = 'R' # disables all autoevents and attempts to restart all services 

    # Pin modes (these are public)
    INPUT = 1  # defined in Arduino.h
    INPUT_PULLUP = 2  # defined in Arduino.h
    OUTPUT = 3  # defined in Arduino.h
    ANALOG = 4  # analog pin in analogInput mode
    PWM = 5  # digital pin in PWM output mode

    EVENT_HANDLER = '@'  # Standard incoming message
    SYSTEM_MSG_HEADER    = '#'  # incoming is a system message 
    ERROR_MESSAGE_HEADER = '~'  # Incoming message: error report
    DEBUG_MESSAGE_HEADER = '!'  # A debug message from the board (can be ignored, probably)

    # ************   END CONSTANTS DEFINITION ****************

    # ************   BEGIN PRIVATE FIELDS DEFINITION ****************

    # __digital_input_pins = []
    # __analog_input_pins = []
    # __pin_mode = []  # FIXME: do we need this at all?

    # PortManager object
    __port_map = None

    # A map from service IDs to actual implementations.
    # FIXME: there could be more than one service with the same ID!
    # (two servos, two distance sensors, etc).
    # use of the dict for python for hashmap
    __services = None

    # The output channel (where we write messages). This should typically be a serial port, but could be anything else.
    # out = AsipWriter()
    __out = None

    __AsipVersionOk = False # flag to indicate that a valid version message has been received
     
    # ************   END PRIVATE FIELDS DEFINITION ****************

    #  A constructor taking the writer as parameter.
    def __init__(self, w=None):

        # Ports, pins, and services initialization
        # self.__pin_mode = [None]*(self.MAX_NUM_DIGITAL_PINS + self.MAX_NUM_ANALOG_PINS)
        self.__services = {}
        self.__port_map = PortManager()

        # constructor also work without writer parameter
        if w is not None:
            self.__out = w
            if self.DEBUG:
                sys.stdout.write('DEBUG: Constructor, writer supplied\n')

        if self.DEBUG:
            sys.stdout.write('DEBUG: End of constructor: arrays and maps created\n')

    # ************ BEGIN PUBLIC METHODS *************

    # returns the port_map object (port_manager)
    def request_port_map(self):
        return self.__port_map

    # This method processes an input received on the serial port.
    # See protocol description for more detailed information.
    def process_input(self, input_str):
        if self.DEBUG:
            sys.stdout.write("DEBUG: received input in process_input is {}\n".format(input_str))
        if input_str[0] == self.EVENT_HANDLER:
            self.__handle_input_event(input_str)
        elif input_str[0] == self.ERROR_MESSAGE_HEADER:
            self.__handle_input_error(input_str)
        elif input_str[0] == self.DEBUG_MESSAGE_HEADER:
            self.__handle_debug_event(input_str)
        else:
            # FIXME: better error handling required! (raise exception) ?
            if self.DEBUG:
                sys.stdout.write("DEBUG: Strange character received at position 0: {}\n".format(input_str))

    # method to request ASIP system info
    def request_info(self):
        self.__out.write("{},{}\n".format(self.SYSTEM_MSG_HEADER,self.SYSTEM_GET_INFO))     
        if self.DEBUG:
            sys.stdout.write("DEBUG: Requesting info {},{}\n".format(self.SYSTEM_MSG_HEADER,self.SYSTEM_GET_INFO))               
    # A method to request the mapping between ports and pins.
    # See process_port_data and process_pin_mapping for additional details on the actual mapping.
    def request_port_mapping(self):
        self.__out.write("{},{}\n".format(self.IO_SERVICE,self.PORT_MAPPING))
        if self.DEBUG:
            sys.stdout.write("DEBUG: Requesting port mapping with {},{}\n".format(self.IO_SERVICE,self.PORT_MAPPING))

    def digital_read(self, pin):
        # FIXME: should add error checking here
        return self.__port_map.digital_read(pin)

    def analog_read(self, pin):
        # FIXME: should add error checking here
        return self.__port_map.analog_read(pin)

    def set_pin_mode(self, pin, mode):
        self.__out.write("{},{},{},{}\n".format(self.IO_SERVICE, self.PIN_MODE, pin, mode))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting pin mode with {},{},{},{}\n".format(self.IO_SERVICE,self.PIN_MODE,pin, mode))

    # A method to write to a digital pin
    def digital_write(self, pin, value):
        self.__out.write("{},{},{},{}\n".format(self.IO_SERVICE, self.DIGITAL_WRITE,pin,value))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting digital pin with {},{},{},{}\n".format(self.IO_SERVICE,self.DIGITAL_WRITE,pin,value))

    # A method to write to an analog pin
    def analog_write(self, pin, value):
        self.__out.write("{},{},{},{}\n".format(self.IO_SERVICE,self.ANALOG_WRITE,pin,value))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting analog pin with {},{},{},{}\n".format(self.IO_SERVICE,self.DIGITAL_WRITE,pin,value))

    # A method to set the autoreport interval (in ms)
    def set_auto_report_interval(self, interval):
        self.__out.write("{},{},{}\n".format(self.IO_SERVICE,self.ANALOG_DATA_REQUEST,interval))
        if self.DEBUG:
            sys.stdout.write(
                "DEBUG: Setting autoreport interval {},{},{}\n".format(self.IO_SERVICE,self.ANALOG_DATA_REQUEST,interval))

    # It is possible to add a service at run-time:
    def add_service(self, service_id, asip_service):
        # If there is already a service with the same ID, we add this new one to the list:
        if service_id in self.__services:
            self.__services[service_id].append(asip_service)
            #self.__services[service_id] = asip_service
        # otherwise, we create a new list, a new key for the dictionary and associate the list to that key
        else:
            new_list = [asip_service]
            self.__services.update({service_id: new_list})

    # FIXME: maybe with python the following method is unuseful (Does the previous do the same?)
    # It is possible to add a list of services at run-time:
    def add_services(self, service_id, asip_ser_list):
        # we create a new key for the dictionary and associate the list to that key
        self.__services.update({service_id: asip_ser_list})

    # Just return the list of services
    def get_services(self):
        return self.__services

    # I'm not sure we want this public... FIXME?
    def get_digital_pins(self):
        return self.__port_map.get_digital_pins()

    # Getter and Setter for output channel
    def get_asip_writer(self):
        return self.__out

    def set_asip_writer(self, w):
        self.__out = w
        
    def isVersionOk(self):
        return self.__AsipVersionOk

    # ************ END PUBLIC METHODS *************

    # ************ BEGIN PRIVATE METHODS *************

    # A method to do what is says on the tin...
    def __handle_input_event(self, input_str):   
        #print("mm: received message {}\n".format(input_str))    
        if self.DEBUG:
            sys.stdout.write("DEBUG: received message {}\n".format(input_str))

        if input_str[1] == self.IO_SERVICE:
            # Digital pins (in port)

            # the port data event is something like: @I,P,4,F
            # this message says the data on port 4 has a value of F
            if input_str[3] == self.PORT_DATA:
                self.__port_map.process_port_data(input_str)
            elif input_str[3] == self.PORT_MAPPING:
                self.__port_map.process_pin_mapping(input_str)
            elif input_str[3] == self.ANALOG_VALUE:
                self.__port_map.process_analog_data(input_str)

            # TODO: implement missing messages!
            else:
                if self.DEBUG:
                    sys.stdout.write("DEBUG: Service not recognised in position 3 for I/O service: {}\n".format(input_str))
            # end of IO_SERVICE
            
        elif input_str[1] == self.SYSTEM_MSG_HEADER:      
            if input_str[3] == self.SYSTEM_GET_INFO:
                field = input_str[5:].split(',')   #extract info fields
                info = 'ASIP version %s.%s running on %s using sketch: %s\n' % (field[0], field[1],field[2], field[4])
                self.__AsipVersionOk = True   #TODO - check that the major version (field[0]) is supported by this client 
                print(info)            

        elif input_str[1] in self.__services.keys():
            # Is this one of the services we know? If this is the case, we call it and we process the input
            # I want a map function here!! For the moment we use a for loop...
            for s in self.__services[input_str[1]]:
                s.process_response(input_str)
                if self.DEBUG:
                    sys.stdout.write("DEBUG: calling process response for key {} and input {}\n".format(s,input))     
        else:
            # We don't know what to do with it.
            if self.DEBUG:
                sys.stdout.write("DEBUG: Event not recognised at position 1: {}\n".format(input_str))

    # To handle a message starting with an error header (this is a form of error reporting from Arduino)
    def __handle_input_error(self, input_str):
        # FIXME: improve error handling
         print("Error message received: {}\n".format(input_str))

    # For the moment we just report board's debug messages on screen
    # FIXME: do something smarter?
    def __handle_debug_event(self, input_str):
        print("dbg msg: {}\n".format(input_str))
Exemple #10
0
 def onPortManager(self):
     PortManager(self)