# Copyright (c) 2014 Kontron Europe GmbH # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA from functools import partial from ..errors import DescriptionError class MessageRegistry(object): def __init__(self): self.registry = dict() def register_class(self, cls): # some sanity checks # (1) class name has to end in Req or Rsp if cls.__name__[-3:] not in ('Req', 'Rsp'): raise DescriptionError('Class name has to end in Req or Rsp') # (2) mandantory fields for attr in ('__netfn__', '__cmdid__', '__default_lun__', '__group_extension__'): if not hasattr(cls, attr): raise DescriptionError('Class has to have attribute "%s"' % attr) # (3) netfn lsb has to be 0 for Req and 1 for Rsp if cls.__name__.endswith('Req') and cls.__netfn__ & 1 != 0: raise DescriptionError('LSB of NetFN of a Request must be 0') if cls.__name__.endswith('Rsp') and cls.__netfn__ & 1 != 1: raise DescriptionError('LSB of NetFN of a Request must be 1') # (4) must not be registered before if cls.__name__ in self.registry: raise DescriptionError('Message %s already registered' % cls.__name__) msg_id = (cls.__netfn__, cls.__cmdid__, cls.__group_extension__) if msg_id in self.registry: raise DescriptionError('Message (%d,%d,%d) already registered (%s)' % (msg_id[0], msg_id[1], msg_id[2], self.registry[msg_id])) # register name self.registry[cls.__name__] = cls # register (netfn, cmdid, group_extension) tuple self.registry[msg_id] = cls # register return cls def create(self, netfn, cmdid, group_extension, *args, **kwargs): return self.registry[(netfn, cmdid, group_extension)](*args, **kwargs) def create_response(self, req): return self.create(req.netfn + 1, req.cmdid, req.group_extension) def create_request_by_name(self, name, *args, **kwargs): return self.registry[name + "Req"](*args, **kwargs) def create_response_by_name(self, name, *args, **kwargs): return self.registry[name + "Rsp"](*args, **kwargs) DEFAULT_REGISTRY = MessageRegistry() register_message_class = partial(MessageRegistry.register_class, DEFAULT_REGISTRY) create_message = partial(MessageRegistry.create, DEFAULT_REGISTRY) create_response_message = partial(MessageRegistry.create_response, DEFAULT_REGISTRY) create_request_by_name = partial(MessageRegistry.create_request_by_name, DEFAULT_REGISTRY) create_response_by_name = partial(MessageRegistry.create_response_by_name, DEFAULT_REGISTRY)