def handle_control_message(self, socket):
        """Handle a control message on the given socket

        Args:
            socket(zmq.Socket): The socket to receive a message and reply on

        """
        message_handlers = {
            "status": self.status,
            "configure": self.configure,
            "request_configuration": self.request_configuration,
            "request_version": self.version,
            "shutdown": self.shutdown,
        }

        # The first message part is a channel ID
        channel_id = socket.recv()

        # The second message part is the IpcMessage
        message = IpcMessage(from_str=socket.recv())
        request_type = message.get_msg_val()

        handler = message_handlers.get(request_type, None)
        if handler is not None:
            reply = handler(message)
        else:
            error = "Unknown request type: {}".format(request_type)
            self._logger.error(error)
            reply = self._construct_reply(
                message.get_msg_val(), message.get_msg_id(), error
            )

        socket.send(channel_id, zmq.SNDMORE)
        socket.send(reply.encode())
Exemple #2
0
 def _callback(self, msg):
     # Handle the multi-part message
     reply = IpcMessage(from_str=msg[0])
     if 'request_configuration' in reply.get_msg_val():
         self._update_configuration(reply.attrs)
     if 'status' in reply.get_msg_val():
         self._update_status(reply.attrs)
    def process_frames(self):

        self.frame_header = Struct('<LLQQL')

        while self._run:

            if (self.ready_channel.poll(100)):

                ready_msg = self.ready_channel.recv()
                ready_decoded = IpcMessage(from_str=ready_msg)

                if ready_decoded.get_msg_type(
                ) == 'notify' and ready_decoded.get_msg_val() == 'frame_ready':

                    frame_number = ready_decoded.get_param('frame')
                    buffer_id = ready_decoded.get_param('buffer_id')
                    self.logger.debug(
                        "Got frame ready notification for frame %d buffer ID %d"
                        % (frame_number, buffer_id))

                    if not self.config.bypass_mode:
                        self.handle_frame(frame_number, buffer_id)

                    release_msg = IpcMessage(msg_type='notify',
                                             msg_val='frame_release')
                    release_msg.set_param('frame', frame_number)
                    release_msg.set_param('buffer_id', buffer_id)
                    self.release_channel.send(release_msg.encode())

                    self.frames_received += 1

                elif ready_decoded.get_msg_type(
                ) == 'notify' and ready_decoded.get_msg_val(
                ) == 'buffer_config':

                    shared_buffer_name = ready_decoded.get_param(
                        'shared_buffer_name')
                    self.logger.debug(
                        'Got shared buffer config notification with name %s' %
                        (shared_buffer_name))

                else:

                    self.logger.error(
                        "Got unexpected message on ready notification channel: %s"
                        % (ready_decoded))

        self.logger.info("Frame processing thread interrupted, terminating")
    def handle_control_message(self, receiver):
        """Handle control message.

        :param: receiver: ZeroMQ channel to receive message from
        """
        channel_id = receiver.recv()
        message_val = ""
        message_id = 0

        try:
            message = IpcMessage(from_str=receiver.recv())
            message_val = message.get_msg_val()
            message_id = message.get_msg_id()

            if message.get_msg_val() == 'status':
                reply = self.handle_status_message(message_id)
            elif message.get_msg_val() == 'request_configuration':
                reply = self.handle_request_config_message(message_id)
            elif message.get_msg_val() == 'request_version':
                reply = self.handle_request_version_message(message_id)
            elif message.get_msg_val() == 'configure':
                self.logger.debug('handling control configure message')
                self.logger.debug(message)
                params = message.attrs['params']
                reply = self.handle_configure_message(params, message_id)
            else:
                reply = IpcMessage(IpcMessage.NACK, message_val, id=message_id)
                reply.set_param('error', 'Unknown message value type')

        except Exception as err:
            self.logger.error(
                'Unexpected Exception handling control message: ' + str(err))
            reply = IpcMessage(IpcMessage.NACK, message_val, id=message_id)
            reply.set_param('error', 'Error processing control message')

        receiver.send(channel_id, zmq.SNDMORE)
        receiver.send(reply.encode())
def test_valid_ipc_msg_from_string():

    # Instantiate a valid message from a JSON string

    json_str = """
                {\"msg_type\":\"cmd\",
                \"msg_val\":\"status\",
                \"timestamp\" : \"2015-01-27T15:26:01.123456\",
                \"id\":322,
                \"params\" : {
                    \"paramInt\" : 1234,
                    \"paramStr\" : \"testParam\",
                    \"paramDouble\" : 3.1415
                  }
                }

             """

    # Instantiate a valid message from the JSON string
    the_msg = IpcMessage(from_str=json_str)

    # Check the message is indeed valid
    assert_true(the_msg.is_valid())

    # Check that all attributes are as expected
    assert_equals(the_msg.get_msg_type(), "cmd")
    assert_equals(the_msg.get_msg_val(), "status")
    assert_equals(the_msg.get_msg_timestamp(), "2015-01-27T15:26:01.123456")
    assert_equals(the_msg.get_msg_id(), 322)

    # Check that all parameters are as expected
    assert_equals(the_msg.get_param("paramInt"), 1234)
    assert_equals(the_msg.get_param("paramStr"), "testParam")
    assert_equals(the_msg.get_param("paramDouble"), 3.1415)

    # Check valid message throws an exception on missing parameter
    with assert_raises(IpcMessageException) as cm:
         missingParam = the_msg.get_param("missingParam")
    ex = cm.exception
    assert_equals(ex.msg, 'Missing parameter missingParam')

    # Check valid message can fall back to default value if parameter missing
    defaultParamValue = 90210
    assert_equals(the_msg.get_param("missingParam", defaultParamValue), defaultParamValue)
def test_round_trip_from_empty_msg():

    # Instantiate an empty message
    the_msg = IpcMessage()

    # Set the message type and value
    msg_type = "cmd"
    the_msg.set_msg_type(msg_type)
    msg_val = "reset"
    the_msg.set_msg_val(msg_val)
    msg_id = 61616
    the_msg.set_msg_id(msg_id)

     # Define and set some parameters
    paramInt1 = 1234;
    paramInt2 = 901201;
    paramInt3 = 4567;
    paramStr = "paramString"

    the_msg.set_param('paramInt1', paramInt1)
    the_msg.set_param('paramInt2', paramInt2)
    the_msg.set_param('paramInt3', paramInt3)
    the_msg.set_param('paramStr',  paramStr)

    # Retrieve the encoded version
    the_msg_encoded = the_msg.encode()

    # Create another message from the encoded version
    msg_from_encoded = IpcMessage(from_str=the_msg_encoded)

    # Validate the contents of all attributes and parameters of the new message
    assert_equal(msg_from_encoded.get_msg_type(), msg_type)
    assert_equal(msg_from_encoded.get_msg_val(),  msg_val)
    assert_equal(msg_from_encoded.get_msg_timestamp(), the_msg.get_msg_timestamp())
    assert_equal(msg_from_encoded.get_msg_id(), the_msg.get_msg_id())
    assert_equal(msg_from_encoded.get_param('paramInt1'), paramInt1)
    assert_equal(msg_from_encoded.get_param('paramInt2'), paramInt2)
    assert_equal(msg_from_encoded.get_param('paramInt3'), paramInt3)
    assert_equal(msg_from_encoded.get_param('paramStr'), paramStr)
Exemple #7
0
    def run_rep(self):
        ''' sends a request, waits for a reply, returns response  '''

        while True:

            try:
                client_address, request = self.socket.recv_multipart()
                request = IpcMessage(from_str=request)
                print("received request : %s from %s" % 
                    (request, client_address.decode()))
                
                # Get the alias device name used in the request
                req_alias = request.get_param("DEVICE")
                
                # get the address of the device
                req_address = self.process_address(request)

                # get the message value (CONFIG/STATUS/READ)
                req_msg_val = request.get_msg_val()
                req_device = None
                req_config = None

                reply_message = IpcMessage(msg_type="CMD", msg_val="NOTIFY")
                
                # Find the device attached to that request address
                for device in self.devices:
                    if req_address == device.get_addr():
                        req_device = device

                if req_msg_val == "CONFIG":
                    req_config = request.get_param("CONFIG")
                    if req_config == "BLINK":
                        req_timeout = request.get_param("TIMEOUT")
                        req_rate = request.get_param("RATE")
                        req_device.set_config(req_config, req_timeout, req_rate)
                        reply_string = "Processed request from %s. %s at address %s blinked for %s seconds. \
                                        Current status is %s." % (client_address.decode(),req_alias, req_address, req_timeout, req_device.get_config())
                    else:
                        req_device.set_config(req_config)
                        reply_string = "Processed Request from %s. Set %s at \
                                        address %s to: %s." % (client_address.decode(),
                                        req_alias, req_address, req_device.get_config())
  
                if req_msg_val == "STATUS":
                    rep_status = req_device.get_status()
                    reply_string = "Processed Request from %s. Status of %s at \
                                    address %s is: %s." % (client_address.decode(), 
                                    req_alias, req_address, rep_status)

                if req_msg_val == "READ":
                    rep_value = req_device.get_data()
                    reply_string = "Processed Request from %s. Value of %s at \
                                    address %s is: %s." % (client_address.decode(), 
                                    req_alias, req_address, rep_value)

                reply_message.set_param("REPLY", reply_string)

                # Encode the message for sending
                reply_message = reply_message.encode()

                # check if its unicode, if so covert to bytes
                if isinstance(reply_message, unicode):
                    reply_message = cast_bytes(reply_message)

                # send a multipart back to the client 
                self.socket.send_multipart([client_address, b"", reply_message,])
            except IpcMessageException as err:
                print("IPC MESSAGE Error Found %s: " % str(err))