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())
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)
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))