示例#1
0
class OpenRpdDriver(HalDriverClient):
    """The OpenRPD base driver

    """

    ##    __metaclass__ = AddLoggerToClass

    def __init__(self,
                 drvName,
                 drvDesc,
                 drvVer,
                 supportedMsgType,
                 supportedNotificationMsgs,
                 interestedNotification=None):
        """

        :param drvName: The driver name, such as Generic Driver
        :param drvDesc: driver for full Cable Labs RPHY support
        :param drvVer: driver version
        :param supportedMsgType: will support all RPHY OpenRPD message types
        :param supportedNotificationMsgs: the supported notification msg types
        :return: OpenRPD Driver object

        NOTES: The 'supportedNotificationMsgs' parameter passed to HalDriverClient
        and then forwarded to HalManager.py, but it seems HalManager.py does NOT
        do anything with this parameter.  Consider remove it from ClientProvision.proto?
        As of now, we don't need to have this parameter.  It just adds confusion!
        """

        if supportedMsgType is None:
            supportedMsgType = OpenRpdMsgHandler.default_supported_msg_types
        super(OpenRpdDriver,
              self).__init__(drvName, drvDesc, drvVer, supportedMsgType,
                             supportedNotificationMsgs, interestedNotification)

        # update the supported messages
        self.HalMsgsHandler = {
            "HalClientRegisterRsp": self.recv_register_msg_cb,
            "HalClientHelloRsp": self.recvHelloRspMsgCb,
            "HalConfig": self.recv_cfg_msg_cb,
            "HalConfigRsp": self.recv_cfg_msg_rsp_cb,
            "HalNotification": self.recvNotificationCb,
        }

        # Handlers for different configuration messages
        self.hal_config_msg_handlers = {
            HalConfigMsg.MsgTypeRpdCapabilities:
            OpenRpdMsgHandler.capabilities_get,
            HalConfigMsg.MsgTypeDsRfPort:
            OpenRpdMsgHandler.config_ds_port,
            HalConfigMsg.MsgTypeDsScQamChannelConfig:
            OpenRpdMsgHandler.config_dsqam_channel,
            HalConfigMsg.MsgTypeDsOfdmChannelConfig:
            OpenRpdMsgHandler.config_dsofdm_channel,
            HalConfigMsg.MsgTypeDsOfdmProfile:
            OpenRpdMsgHandler.config_dsofdm_profile,
            HalConfigMsg.MsgTypeDsRfPortPerf:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeDsScQamChannelPerf:
            OpenRpdMsgHandler.req_dsqam_channel_status,
            HalConfigMsg.MsgTypeDsOfdmChannelPerf:
            OpenRpdMsgHandler.req_dsofdm_channel_status,
            HalConfigMsg.MsgTypeDsOob551IPerf:
            OpenRpdMsgHandler.req_oob551_mod_status,
            HalConfigMsg.MsgTypeDsOob552Perf:
            OpenRpdMsgHandler.req_oob552_mod_status,
            HalConfigMsg.MsgTypeNdfPerf:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeUsRfPortPerf:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeUsScQamChannelConfig:
            OpenRpdMsgHandler.config_usatdma_channel,
            HalConfigMsg.MsgTypeUsOfdmaChannelConfig:
            OpenRpdMsgHandler.config_usofdma_channel,
            HalConfigMsg.MsgTypeUsOfdmaInitialRangingIuc:
            OpenRpdMsgHandler.config_dummy,
            HalConfigMsg.MsgTypeUsOfdmaFineRangingIuc:
            OpenRpdMsgHandler.config_dummy,
            HalConfigMsg.MsgTypeUsOfdmaDataRangingIuc:
            OpenRpdMsgHandler.config_dummy,
            HalConfigMsg.MsgTypeUsOfdmaDataIuc:
            OpenRpdMsgHandler.config_dummy,
            HalConfigMsg.MsgTypeUsOfdmaSubcarrierCfgState:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeUsScQamChannelPerf:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeUsOfdmaChannelPerf:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeUsOob551IPerf:
            OpenRpdMsgHandler.req_oob551_demod_status,
            HalConfigMsg.MsgTypeUsOob552Perf:
            OpenRpdMsgHandler.req_oob552_demod_status,
            HalConfigMsg.MsgTypeNdrPerf:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeSidQos:
            OpenRpdMsgHandler.config_sid_qos,
            # L2TPv3 messages
            HalConfigMsg.MsgTypeL2tpv3CapabilityQuery:
            OpenRpdMsgHandler.capabilities_get,
            HalConfigMsg.MsgTypeL2tpv3SessionReqNone:
            OpenRpdMsgHandler.req_depi_pw,
            HalConfigMsg.MsgTypeL2tpv3SessionReqDsOfdm:
            OpenRpdMsgHandler.req_depi_pw,
            HalConfigMsg.MsgTypeL2tpv3SessionReqDsOfdmPlc:
            OpenRpdMsgHandler.req_depi_pw,
            HalConfigMsg.MsgTypeL2tpv3SessionReqDsScqam:
            OpenRpdMsgHandler.req_depi_pw,
            HalConfigMsg.MsgTypeL2tpv3SessionReqUsAtdma:
            OpenRpdMsgHandler.req_uepi_pw,
            HalConfigMsg.MsgTypeL2tpv3SessionReqUsOfdma:
            OpenRpdMsgHandler.req_uepi_pw,
            HalConfigMsg.MsgTypeL2tpv3SessionReqScte551Fwd:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeL2tpv3SessionReqScte551Ret:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeL2tpv3SessionReqScte552Fwd:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeL2tpv3SessionReqScte552Ret:
            OpenRpdMsgHandler.req_dummy,
            HalConfigMsg.MsgTypeL2tpv3SessionReqNdf:
            OpenRpdMsgHandler.req_ndf,
            HalConfigMsg.MsgTypeL2tpv3SessionReqNdr:
            OpenRpdMsgHandler.req_ndr,

            # Ptp
            # HalConfigMsg.MsgTypeRdtiConfig:                  config_docsis_timer
            HalConfigMsg.MsgTypeL2tpv3CinIfAssignment:
            OpenRpdMsgHandler.cin_if_assign,
            HalConfigMsg.MsgTypeL2tpv3LcceIdAssignment:
            OpenRpdMsgHandler.lcce_id_assign,

            # VspAvpQuery
            HalConfigMsg.MsgTypeVspAvpExchange:
            OpenRpdMsgHandler.vsp_avp_handler,
            # RcpVendorSpecificTlv
            HalConfigMsg.MsgTypeRcpVendorSpecific:
            OpenRpdMsgHandler.vsp_tlv_handler,
        }

        self.disconnected = True
        self.dispatcher = Dispatcher()

        # setup the logging
        self.logger = OpenRpdMsgHandler.get_msg_handler_logger()
        self.logger.info("OpenRPD Driver Initialized")
        self.seqNum = 0

    # start modeled from HalPtpDriver.py

    def start(self, simulate_mode=False):
        """start poll the transport socket

        :return:

        """
        self.logger.info("Setup the Hal Transport connection...")
        self.connectionSetup()
        self.logger.info("Connection setup done...")

        self.logger.info("Register the driver with the Hal manager...")
        self.register(self.drvID)
        self.logger.info("End of register...")

        self.dispatcher.loop()

    def recv_register_msg_cb(self, cfg):
        """the callback handler for the configuration message
        Modified from base class by registering the sockets
        with dispatcher.

        :param cfg: the configuration message received from the Hal
        :return:

        """
        # self.logger.debug("Recv a Message from the Hal:" % str(cfg.msg))

        if cfg.msg.Rsp.Status != HalCommon_pb2.SUCCESS:
            self.logger.error("Cannot register to Hal, reason[%s]" %
                              cfg.msg.Rsp.ErrorDescription)
            return

        self.drvID = cfg.msg.ClientID

        # Setup the push and pull connection
        self.pullPath = cfg.msg.PathFromHalToClient
        self.pushPath = cfg.msg.PathFromClientToHal

        # get the index of the path
        index = self._getIndexFromPath()
        if index == -1:
            self.logger.error("Cannot get index from the path [%s]" %
                              self.pushPath)
            return
        if self.index == -1:
            self.index = index
            self.pushSock = HalTransport(
                HalTransport.HalTransportClientAgentPull,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPushMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            self.pullSock = HalTransport(
                HalTransport.HalTransportClientAgentPush,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPullMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            # register driver's sockets with the dispatcher
            self.dispatcher.fd_register(self.pullSock.socket, zmq.POLLIN,
                                        self.openrpd_drv_hal_cb)
            self.dispatcher.fd_register(self.pushSock.monitor, zmq.POLLIN,
                                        self.openrpd_drv_hal_cb)
            self.dispatcher.fd_register(self.pullSock.monitor, zmq.POLLIN,
                                        self.openrpd_drv_hal_cb)

        # send Hello To Hal
        self.sayHelloToHal()
        if (None is not self.interestedNotification):
            self.sendInterestedNotifications(self.interestedNotification)

        self.disconnected = False

        return

    def connectionSetup(self):
        """Create the connection to the mgr

        :return:

        """
        self.logger.info("Create the connection to the mgr....")
        # Create a connection to Hal driver mgr
        self.mgrConnection = HalTransport(
            HalTransport.HalTransportClientMgr,
            HalTransport.HalClientMode,
            disconnectHandlerCb=self.disconnectCb)
        self.mgrConnection.connects()

        self.HalMsgsHandler[
            self.mgrConnection.socket] = self.recv_register_msg_cb

        # register the mgr socket with the dispatcher
        self.dispatcher.fd_register(self.mgrConnection.socket, zmq.POLLIN,
                                    self.openrpd_drv_hal_cb)
        self.dispatcher.fd_register(self.mgrConnection.monitor, zmq.POLLIN,
                                    self.openrpd_drv_hal_cb)

    def connection_cleanup(self):
        """Close the connection to the mgr

        :return:

        """
        if self.disconnected:
            self.logger.debug("A previous event has been processed, skip it!")
            return

        if self.mgrConnection is not None:
            self.dispatcher.fd_unregister(self.mgrConnection.socket)
            self.dispatcher.fd_unregister(self.mgrConnection.monitor)
            self.mgrConnection.socket.disable_monitor()
            self.mgrConnection.monitor.close()
            self.mgrConnection.socket.close()

        if self.pullSock is not None:
            self.dispatcher.fd_unregister(self.pullSock.socket)
            self.dispatcher.fd_unregister(self.pullSock.monitor)
            self.pullSock.socket.disable_monitor()
            self.pullSock.monitor.close()
            self.pullSock.socket.close()

        if self.pushSock is not None:
            self.dispatcher.fd_unregister(self.pushSock.monitor)
            self.pushSock.socket.disable_monitor()
            self.pushSock.monitor.close()
            self.pushSock.socket.close()

        self.disconnected = True

    def disconnectCb(self, msg):
        """A disconnect condition has been detected, 
        clean up the connection and then reconnect
        and re-register with the Hal.

        :param msg:
        :return:

        """
        self.logger.error("Detected disconnected condition")

        if self.disconnected:
            self.logger.info("A previous event has been processed, skip it!")
            return
        self.logger.info("Detected disconnected, registering again")
        # clean up the push and pull socket
        self.dispatcher.fd_unregister(self.mgrConnection.socket)
        self.dispatcher.fd_unregister(self.mgrConnection.monitor)
        self.mgrConnection.monitor.close()
        self.mgrConnection.close()

        # re-register the message
        self.connectionSetup()
        # The zmq lower part will handle the reconnect
        self.register(self.drvID)

        self.disconnected = True

    def openrpd_drv_hal_cb(self, sock, mask):
        self.logger.debug("Driver received hal cb event")
        if self.pushSock is not None and sock == self.pushSock.monitor:
            self.pushSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.pullSock is not None and sock == self.pullSock.monitor:
            self.pullSock.monitorHandler(recv_monitor_message(sock))
            return

        if sock == self.mgrConnection.monitor:
            self.mgrConnection.monitorHandler(recv_monitor_message(sock))
            return

        while sock.getsockopt(zmq.EVENTS) and zmq.POLLIN:
            try:
                bin = sock.recv(flags=zmq.NOBLOCK)
                msg = HalMessage.DeSerialize(bin)
                self.logger.debug("Got a zmq msg:%s type:%s" %
                                  (msg.msg, msg.type))
                if msg.type in self.HalMsgsHandler:
                    handler = self.HalMsgsHandler[msg.type]
                    handler(msg)
            except zmq.ZMQError as e:
                self.logger.debug(
                    "Got an error when trying with nonblock read:" + str(e))
                break
            except Exception as e:
                self.logger.error("Got an un-expected error:%s", str(e))
                break

    def recvNotificationCb(self, ntf):
        """Receive a notification message from the HAL.

        :param ntf:
        :return:

        """
        try:
            handler = self.hal_config_msg_handlers[ntf.msg.HalNotificationType]
            self.logger.info("Receive a interest notification message:" +
                             str(ntf.msg))

            if not isinstance(ntf, HalMessage):
                raise AttributeError("Invalid HAL message passed")

            ntf = handler(ntf)
            if None is not ntf:
                self.send_cfg_msg(HalConfigMsg.MsgTypeVspAvpExchange,
                                  ntf.msg.HalNotificationPayLoad)
            else:
                self.logger.info("Notification message return is None")
        except Exception as e:
            self.logger.error("Got an error:%s, the ntf msg:%s", str(e),
                              ntf.msg)

    def send_cfg_msg(self, cfgMsgType, payload):
        msg = HalMessage("HalConfig",
                         SrcClientID=self.drvID,
                         CfgMsgType=cfgMsgType,
                         SeqNum=self.seqNum,
                         CfgMsgPayload=payload)
        self.logger.debug("sending config - type: %d, msg: %s" %
                          (cfgMsgType, msg))
        self.pushSock.send(msg.Serialize())
        self.seqNum += 1
        return

    def send_cfg_rsp_msg(self, cfg):
        """The configuration response routine

        :param cfg: The original configuration message
        :return:

        """
        result = HalCommon_pb2.SUCCESS
        cfgMsg = cfg.msg
        l2tpcfgmsgType = (HalConfigMsg.MsgTypeL2tpv3SessionReqDsOfdm,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqDsOfdmPlc,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqDsScqam,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqUsAtdma,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqUsOfdma,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqScte551Fwd,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqScte551Ret,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqScte552Fwd,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqScte552Ret,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqNdf,
                          HalConfigMsg.MsgTypeL2tpv3SessionReqNdr,
                          HalConfigMsg.MsgTypeL2tpv3CinIfAssignment,
                          HalConfigMsg.MsgTypeL2tpv3LcceIdAssignment)
        if cfgMsg.CfgMsgType in l2tpcfgmsgType:
            rsp = L2tpv3Hal_pb2.t_l2tpSessionRsp()
            req = L2tpv3Hal_pb2.t_l2tpSessionReq()
            req.ParseFromString(cfgMsg.CfgMsgPayload)
            # fill session_selector
            rsp.session_selector.local_session_id = req.session_selector.local_session_id
            rsp.session_selector.remote_session_id = req.session_selector.remote_session_id
            rsp.session_selector.local_ip = req.session_selector.local_ip
            rsp.session_selector.remote_ip = req.session_selector.remote_ip
            rsp.result = True
        elif (cfgMsg.CfgMsgType == HalConfigMsg.MsgTypeVspAvpExchange):
            rsp = L2tpv3VspAvp_pb2.t_l2tpVspAvpMsg()
            rsp.ParseFromString(cfgMsg.CfgMsgPayload)
            self.logger.debug(
                "vsp_avp_handler re-parse srcClientID: %s, Seq num:  %d, "
                "op: %d, vid %d, attr %d, strVal %s" %
                (cfg.msg.SrcClientID, cfg.msg.SeqNum, rsp.oper, rsp.vendorId,
                 rsp.attrType, rsp.attrValBuf))
            if rsp.rspCode == L2tpv3VspAvp_pb2.t_l2tpVspAvpMsg(
            ).VSP_AVP_STATUS_FAILURE:
                # send HalConfigRsp with failure status if OpenRPD driver can't handle this.
                result = HalCommon_pb2.FAILED
        elif (cfgMsg.CfgMsgType == HalConfigMsg.MsgTypeRcpVendorSpecific):
            rsp = t_RcpMessage()
            rsp.ParseFromString(cfgMsg.CfgMsgPayload)
            self.logger.debug("send_cfg_rsp_msg payload: %s, result: %d" %
                              (rsp.RpdDataMessage.RpdData, rsp.RcpDataResult))
        else:
            rsp = t_RcpMessage()
            rsp.ParseFromString(cfgMsg.CfgMsgPayload)
            self.logger.debug("send_cfg_rsp_msg payload: %s" %
                              rsp.RpdDataMessage.RpdData)
            rsp.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
        payload = rsp.SerializeToString()

        self.logger.debug("cfg response srcClientID: %s, Seq num:  %d" %
                          (cfgMsg.SrcClientID, cfgMsg.SeqNum))
        msg = HalMessage("HalConfigRsp",
                         SrcClientID=cfgMsg.SrcClientID,
                         SeqNum=cfgMsg.SeqNum,
                         Rsp={
                             "Status": HalCommon_pb2.SUCCESS,
                             "ErrorDescription": ""
                         },
                         CfgMsgType=cfgMsg.CfgMsgType,
                         CfgMsgPayload=payload)
        self.logger.debug("sending cfg response - type: %d, msg: %s" %
                          (cfgMsg.CfgMsgType, msg))
        self.pushSock.send(msg.Serialize())

    def recv_cfg_msg_rsp_cb(self, cfg):
        cfgMsg = cfg.msg
        self.logger.debug("receive cfg response - type: %d" %
                          (cfgMsg.CfgMsgType))
        pass

    def recv_cfg_msg_cb(self, cfg):
        """Receive a configuration message from the Hal, processing it

        :param cfg:
        :return:

        """
        try:
            handler = self.hal_config_msg_handlers[cfg.msg.CfgMsgType]
            self.logger.info("Received a cfg message type: %d",
                             cfg.msg.CfgMsgType)

            if not isinstance(cfg, HalMessage):
                raise AttributeError("Invalid HAL message passed")

            cfg = handler(cfg)
            self.send_cfg_rsp_msg(cfg)
        except Exception as e:
            self.logger.error("Got an error:%s, the cfg msg:%s", str(e),
                              cfg.msg)

    def cleanup_sockets(self):
        for fd in self.fd_to_socket:
            sock = self.fd_to_socket[fd]
            self.poller.unregister(sock)
            sock.close()
        self.fd_to_socket.clear()
示例#2
0
class ProvMgrHalDriver(HalDriverClient):
    __metaclass__ = AddLoggerToClass

    ntfmsg_list = [
        MsgTypeRpdCapabilities,
    ]
    cfgmsg_list = [
        MsgTypeCcapCoreIdentification,
        MsgTypeRedundantCoreIpAddress,
        MsgTypeRpdCtrl,
    ]

    def __init__(self,
                 drvName,
                 drvDesc,
                 drvVer,
                 supportedMsgType,
                 supportedNotificationMsgs,
                 interestedNotification,
                 dispatcher,
                 logConfigurePath=None,
                 mgr=None):
        """

        :param drvName:
        :param drvDesc:
        :param drvVer:
        :param supportedMsgType:
        :param supportedNotificationMsgs:
        :param dispatcher:
        :param logConfigurePath:
        :param mgr:
        """
        super(ProvMgrHalDriver,
              self).__init__(drvName, drvDesc, drvVer, supportedMsgType,
                             supportedNotificationMsgs, interestedNotification)

        self.mgr = mgr
        self.rpd_cap = None
        self.dispatcher = dispatcher

        self.HalConfigMsgHandlers = {
            MsgTypeCcapCoreIdentification: self.recvCcapCoreIdentification,
            MsgTypeRedundantCoreIpAddress: self.recvRedundantCoreIpAddress,
            MsgTypeRpdCtrl: self.recvRpdResetCtrl,
        }

        self.HalNtfHandlers = {
            MsgTypeRpdCapabilities: self.recvRpdCapabilities,
        }

        self.HalConfigMsgRspHandlers = {
            MsgTypeRpdCapabilities: self.recMsgTypeRpdCapabilitiesRspCb,
        }

    RESET_CTRL_FILENAME = '/rpd/config/reset_ctrl'

    def recvRegisterMsgCb(self, cfg):
        # self.logger.debug("Recv a Message from the Hal:" % str(cfg.msg))

        if cfg.msg.Rsp.Status != HalCommon_pb2.SUCCESS:
            self.logger.error("Cannot register to Hal, reason[%s]" %
                              cfg.msg.Rsp.ErrorDescription)
            return

        self.drvID = cfg.msg.ClientID

        # Setup the push and pull connection
        self.pullPath = cfg.msg.PathFromHalToClient
        self.pushPath = cfg.msg.PathFromClientToHal

        # get the index of the path
        index = self._getIndexFromPath()
        if index == -1:
            self.logger.error("Cannot get index from the path [%s]" %
                              self.pushPath)
            return
        if self.index == -1:
            self.index = index
            self.pushSock = HalTransport(
                HalTransport.HalTransportClientAgentPull,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPushMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            self.pullSock = HalTransport(
                HalTransport.HalTransportClientAgentPush,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPullMode,
                disconnectHandlerCb=self.connectionDisconnectCb)
            # register to the poller
            self.dispatcher.fd_register(self.pullSock.socket, zmq.POLLIN,
                                        self.provmgr_cb)
            self.dispatcher.fd_register(self.pushSock.monitor, zmq.POLLIN,
                                        self.provmgr_cb)
            self.dispatcher.fd_register(self.pullSock.monitor, zmq.POLLIN,
                                        self.provmgr_cb)
        # send Hello To Hal
        self.sayHelloToHal()
        if self.interestedNotification is not None:
            self.sendInterestedNotifications(self.interestedNotification)

        self.disconnected = False

        return

    def sendCfgRspMsg(self, cfg, rsp=None):
        """The configuration response routine, the driver implementor should
        fill sth into this function.

        :param cfg: The original configuration message
        :param rsp: respond
        :return:

        """
        cfgMsg = cfg.msg
        msg = HalMessage("HalConfigRsp",
                         SrcClientID=cfgMsg.SrcClientID,
                         SeqNum=cfgMsg.SeqNum,
                         Rsp=rsp,
                         CfgMsgType=cfgMsg.CfgMsgType,
                         CfgMsgPayload=cfgMsg.CfgMsgPayload)
        self.send(msg.Serialize())

    def recvCfgMsgCb(self, cfgMsg):
        """Receive a configuration message from the Hal, processing it.

        :param cfgMsg:
        :return:

        """
        try:
            msgType = cfgMsg.msg.CfgMsgType
            if msgType not in self.HalConfigMsgHandlers \
                    or self.HalConfigMsgHandlers[msgType] is None:
                rsp = {
                    "Status": HalCommon_pb2.NOTSUPPORTED,
                    "ErrorDescription": "msgType %d is not supported" % msgType
                }
            else:
                rsp = self.HalConfigMsgHandlers[msgType](cfgMsg.msg)

        except Exception as e:  # pragma: no cover
            self.logger.error("Got an error:%s, the cfg msg:%s", str(e),
                              cfgMsg.msg)
            rsp = {
                "Status":
                HalCommon_pb2.FAILED,
                "ErrorDescription":
                "Process configuration failed, reason:%s" % str(e)
            }

        self.sendCfgRspMsg(cfgMsg, rsp)

    def recvCfgMsgRspCb(self, cfg):
        """Receive a configuration response message from the Hal, processing it.

        :param cfg:
        :return:

        """
        self.logger.debug("Recv a configuration response message:" +
                          str(cfg.msg.CfgMsgType))
        if cfg.msg.CfgMsgType in self.HalConfigMsgRspHandlers:
            cb = self.HalConfigMsgRspHandlers[cfg.msg.CfgMsgType]
            cb(cfg)

    def sendNotificationMsg(self, notificationType, notificationPayload):
        """Send a notification to Hal.

        :param notificationType: The notification type, the client must
         declare the notification type to Hal first
        :param notificationPayload: the string payload, Hal will not touch
         this part
        :return:

        """
        self.logger.debug("send a a notification message to Hal")
        if self.disconnected:
            self.logger.warning(
                "The client is on disconnected state,"
                " skip to send the message, notification type:%s",
                notificationType)
            return

        if notificationType is None or not isinstance(notificationPayload,
                                                      str):
            self.logger.warning("Cannot send a None or incorrect type to HAL, "
                                "str is required for msg.")
            return

        notification = HalMessage("HalNotification",
                                  ClientID=self.drvID,
                                  HalNotificationType=notificationType,
                                  HalNotificationPayLoad=notificationPayload)
        self.send(notification.Serialize())

    def recvNotificationCb(self, ntf):
        """Receive a notification message from the HAL.

        :param ntf:
        :return:

        """
        self.logger.info("Receive a interest notification message:" +
                         str(ntf.msg))
        self.recvNtf += 1
        try:
            msgType = ntf.msg.HalNotificationType
            if msgType in self.HalNtfHandlers:
                self.HalNtfHandlers[msgType](ntf.msg.HalNotificationPayLoad)
            else:
                self.logger.debug(
                    "Receive a interest notification message: no handler for %s",
                    str(msgType))
        except Exception as e:
            self.logger.error("Got an error:%s, the ntf msg:%s", str(e),
                              str(msgType))

    def recvHelloRspMsgCb(self, hello):
        """Call back for Hello Message.

        :param hello:
        :return:

        """
        self.logger.debug("Recv a hello message")
        self.sendRpdCapReq()

    def connectionSetup(self, dispatcher):
        """Create the connection to the mgr and setup the poller.

        :return:

        """
        self.logger.debug("Create the connection to the mgr....")
        # Create a connection to Hal driver mgr
        self.mgrConnection = HalTransport(
            HalTransport.HalTransportClientMgr,
            HalTransport.HalClientMode,
            disconnectHandlerCb=self.connectionDisconnectCb)

        # create the poller
        if self.poller is None:
            self.poller = dispatcher.get_poll()

        # register the mgr socket
        dispatcher.fd_register(self.mgrConnection.socket, zmq.POLLIN,
                               self.provmgr_cb)
        dispatcher.fd_register(self.mgrConnection.monitor, zmq.POLLIN,
                               self.provmgr_cb)

    def connectionDisconnectCb(self, msg):
        """The connection has been detected disconnected , register it again.

        :param msg:
        :return:

        """

        if self.disconnected:
            self.logger.debug("A previous event has been processed, skip it!")
            return
        self.logger.debug("Detected disconnected, register again")

        self.poller.unregister(self.mgrConnection.socket)
        self.poller.unregister(self.mgrConnection.monitor)
        self.mgrConnection.socket.disable_monitor()
        self.mgrConnection.monitor.close()
        self.mgrConnection.close()

        # re-register the message
        self.connectionSetup(self.dispatcher)
        self.register(self.drvID)
        # The zmq lower part will handle the reconnect

        self.disconnected = True

    def start(self):
        """start poll the transport socket.

        :return:

        """
        self.logger.debug("Start the driver poll...")
        try:
            self.connectionSetup(self.dispatcher)
            self.register(self.drvID)
        except Exception as e:
            self.logger.warn("ProvMgr hal client start fail exception %s",
                             str(e))

    def provmgr_cb(self, sock, mask):
        if self.pushSock is not None and sock == self.pushSock.monitor:
            self.pushSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.pullSock is not None and sock == self.pullSock.monitor:
            self.pullSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.mgrConnection is not None and sock == self.mgrConnection.monitor:
            self.mgrConnection.monitorHandler(recv_monitor_message(sock))
            return

        while sock.getsockopt(zmq.EVENTS) and zmq.POLLIN:
            try:
                bin = sock.recv(flags=zmq.NOBLOCK)
                msg = HalMessage.DeSerialize(bin)
                if msg.type in self.HalMsgsHandler:
                    handler = self.HalMsgsHandler[msg.type]
                    handler(msg)
            except zmq.ZMQError as e:
                self.logger.debug(
                    "Got an error when trying with non-block read:" + str(e))
                break
            except Exception as e:
                self.logger.warn(
                    "Exception happens when provmgr hal recv socket, reason:%s"
                    % str(e))
                break

    def DeSerializeConfigMsgPayload(self, cfgMsg):
        if cfgMsg.CfgMsgPayload is None:
            return None
        cfgMsgPayload = t_RcpMessage()
        cfgMsgPayload.ParseFromString(cfgMsg.CfgMsgPayload)
        return cfgMsgPayload

    def recvCcapCoreIdentification(self, cfgMsg):
        rcp_msg = self.DeSerializeConfigMsgPayload(cfgMsg)
        if rcp_msg is None:
            return {
                "Status": HalCommon_pb2.FAILED,
                "ErrorDescription": "DeSerialize ConfigMsgPayload fail"
            }
        self.logger.debug(
            "ProvMgr driver receive Config CcapCoreIdentification %s" %
            str(rcp_msg))
        if rcp_msg.RpdDataMessage.RpdDataOperation == t_RpdDataMessage.RPD_CFG_READ:
            rcp_msg.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
            del rcp_msg.RpdDataMessage.RpdData.CcapCoreIdentification[0]
            for key in CcapCoreIdentification.get_keys():
                ccapCoreIdent = rcp_msg.RpdDataMessage.RpdData.CcapCoreIdentification.add(
                )
                ccapCore = CcapCoreIdentification(key)
                ccapCore.read()

                ccapCoreIdent.Index = key
                ccapCoreIdent.CoreId = ccapCore.core_id
                ccapCoreIdent.CoreIpAddress = ccapCore.core_ip_addr
                ccapCoreIdent.IsPrincipal = ccapCore.is_principal
                ccapCoreIdent.CoreName = ccapCore.core_name
                ccapCoreIdent.VendorId = ccapCore.vendor_id
                ccapCoreIdent.InitialConfigurationComplete = ccapCore.initial_configuration_complete
                ccapCoreIdent.MoveToOperational = ccapCore.move_to_operational
                ccapCoreIdent.CoreFunction = ccapCore.core_function
                ccapCoreIdent.ResourceSetIndex = ccapCore.resource_set_index
                ccapCoreIdent.CoreMode = ccapCore.core_mode
                self.logger.debug("ProvMgr driver rsp ccapCoreIdent tlv %s" %
                                  ccapCoreIdent)
            cfgMsg.CfgMsgPayload = rcp_msg.SerializeToString()

            rsp = {
                "Status": HalCommon_pb2.SUCCESS,
                "ErrorDescription": "Serialize ConfigMsgPayload success"
            }
            return rsp
        if rcp_msg.RpdDataMessage.RpdDataOperation == t_RpdDataMessage.RPD_CFG_WRITE or \
           rcp_msg.RpdDataMessage.RpdDataOperation == t_RpdDataMessage.RPD_CFG_ALLOCATE_WRITE:
            rsp = {
                "Status":
                HalCommon_pb2.SUCCESS_IGNORE_RESULT,
                "ErrorDescription":
                "manager hal ignore write and allocate write for ccapCoreIdentification"
            }
            return rsp

    def recvRedundantCoreIpAddress(self, cfgMsg):
        rcp_msg = self.DeSerializeConfigMsgPayload(cfgMsg)
        self.logger.info("ProvMgr driver receive RedundantCoreIpAddress %s" %
                         str(rcp_msg))
        rsp = {"Status": HalCommon_pb2.SUCCESS, "ErrorDescription": "success"}
        return rsp

    def recvRpdResetCtrl(self, cfgMsg):
        rcp_msg = self.DeSerializeConfigMsgPayload(cfgMsg)
        if rcp_msg is None:
            return {
                "Status": HalCommon_pb2.FAILED,
                "ErrorDescription": "DeSerialize ConfigMsgPayload fail"
            }
        self.logger.debug("\nProvMgr receive RpdResetCtrl:" + str(rcp_msg))
        operation = rcp_msg.RpdDataMessage.RpdDataOperation

        recv_rcp_msg = rcp_msg.RpdDataMessage.RpdData
        if recv_rcp_msg.HasField("RpdCtrl") and recv_rcp_msg.RpdCtrl.HasField(
                "ResetCtrl"):
            if operation not in [
                    t_RpdDataMessage.RPD_CFG_WRITE,
                    t_RpdDataMessage.RPD_CFG_READ
            ]:
                return {
                    "Status":
                    HalCommon_pb2.FAILED,
                    "ErrorDescription":
                    "Operation %d for RpdResetCtrl is not supported" %
                    operation
                }
            rcp_rpd_resetctrl = recv_rcp_msg.RpdCtrl.ResetCtrl
            if operation == t_RpdDataMessage.RPD_CFG_WRITE:
                reset = rcp_rpd_resetctrl.Reset
                reset_type = rcp_tlv_def.RESET_TYPE[reset]
                with open(self.RESET_CTRL_FILENAME, 'w') as f:
                    f.write(str(reset) + ":" + str(reset_type) + "\n")
                for ccap_core in CCAPCore.ccap_core_db.values():
                    ccap_core.del_ccap_core()
                SysTools.reboot(reset_type)
            if operation == t_RpdDataMessage.RPD_CFG_READ:
                try:
                    with open(self.RESET_CTRL_FILENAME, 'r') as fr:
                        reset_rd = fr.read()
                        rcp_rpd_resetctrl.Reset = int(reset_rd.strip(":")[0])
                except IOError:
                    # file don't exist,skip check
                    pass
            cfgMsg.CfgMsgPayload = rcp_msg.SerializeToString()
            return {
                "Status":
                HalCommon_pb2.SUCCESS,
                "ErrorDescription":
                "ProMgr handle RpdResetCtrl success for %d" % operation
            }
        else:
            return {
                "Status": HalCommon_pb2.SUCCESS_IGNORE_RESULT,
                "ErrorDescription": "ProvMgr Do not Have RpdCtrl Filed."
            }

    def valid_rpd_cap(self, rcp_rpd_cap):
        # check the instance
        if not isinstance(rcp_rpd_cap, t_RpdCapabilities):
            return False
        # check it is not the default value
        default_cap = t_RpdCapabilities()
        GCPObject.default_gpb(default_cap)
        if rcp_rpd_cap == default_cap:
            return False

        return True

    def recMsgTypeRpdCapabilitiesRspCb(self, halrspmsg):
        try:
            # Check the status
            if halrspmsg.msg.Rsp.Status != HalCommon_pb2.SUCCESS:
                # yes, we recv a error message from HAL
                self.logger.warning("Receive a hal fail message:%s" %
                                    halrspmsg.msg)
                return False

            cfg_rsp = t_RcpMessage()
            cfg_rsp.ParseFromString(halrspmsg.msg.CfgMsgPayload)
            if cfg_rsp.RcpDataResult != t_RcpMessage.RCP_RESULT_OK:
                # yes we recv a error msg from driver
                self.logger.warning("Recv a driver fail message:%s" %
                                    str(cfg_rsp))
                return False
            rcp_rpd_cap = cfg_rsp.RpdDataMessage.RpdData.RpdCapabilities
            if not self.valid_rpd_cap(rcp_rpd_cap):
                self.logger.debug(
                    "Receive invalid RpdCapabilities rsp from driver")
                return False
            if not self.rpd_cap:
                self.rpd_cap = t_RpdCapabilities()
            self.rpd_cap.CopyFrom(rcp_rpd_cap)
            self.logger.debug("Receive RpdCapabilities rsp from driver")
            return True
        except Exception as e:
            self.logger.warning("cap fail %s", str(e))
            return False

    def recvRpdCapabilities(self, ntfMsg):
        rpd_cap = t_RpdCapabilities()
        rpd_cap.ParseFromString(ntfMsg)
        if not self.valid_rpd_cap(rpd_cap):
            self.logger.warning(
                "ProvMgr receive invalid rpdCapabilities notification from driver"
            )
            return
        self.rpd_cap = rpd_cap
        self.logger.debug("Receive rpdCapabilities notification:  %s",
                          str(self.rpd_cap))
        return

    def sendRpdCapReq(self):
        try:
            if self.rpd_cap:
                self.logger.debug(
                    "Already has Rpd cap in store, no need to send req")
                return True
            rcp_msg = t_RcpMessage()
            rcp_msg.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
            rcp_msg.RcpMessageType = t_RcpMessage.RPD_CONFIGURATION
            rpd_data_msg = t_RpdDataMessage()
            rpd_data_msg.RpdDataOperation = t_RpdDataMessage.RPD_CFG_READ
            rcp_cfg = config()
            sub_tlv = rcp_cfg.RpdCapabilities
            GCPObject.default_gpb(gpb=sub_tlv)
            rpd_data_msg.RpdData.CopyFrom(rcp_cfg)
            rcp_msg.RpdDataMessage.CopyFrom(rpd_data_msg)

            cfgMsgContent = rcp_msg.SerializeToString()
            msg = HalMessage("HalConfig",
                             SrcClientID=self.drvID,
                             SeqNum=self.seqNum,
                             CfgMsgType=MsgTypeRpdCapabilities,
                             CfgMsgPayload=cfgMsgContent)
            self.send(msg.Serialize())
            self.seqNum += 1
            self.logger.debug("send RPD capabilities req to hal driver")
            return True
        except Exception as e:
            self.logger.warning("send RPD cap req failed :%s", str(e))
            return False

    def sendOperationalStatusNtf(self, operational):
        """
        :param operational:  True or False to represent the current operational status
        :return:
        """
        led_msg = t_LED()
        led_msg.setLed.ledType = led_msg.LED_TYPE_STATUS
        led_msg.setLed.color = led_msg.LED_COLOR_GREEN
        if operational:
            led_msg.setLed.action = led_msg.LED_ACTION_LIT
        else:
            led_msg.setLed.action = led_msg.LED_ACTION_DARK
        self.logger.debug("Set led notification message: %s", led_msg)
        self.sendNotificationMsg(MsgTypeSetLed, led_msg.SerializeToString())
示例#3
0
    def test_eventHandlerMonitor(self):
        """test HalTransport#monitorHandler,

        check whether the
        EVENT_DISCONNECTED can be handle, if status is false case fail

        check
        whether the EVENT_CONNECT_RETRIED can be handle, if status before the
        timeout/after timeout was wrong, case fail

        check whether the
        EVENT_CLOSED can be handle, if status before the timeout/after timeout
        was wrong, case fail

        check whether the unnormal event can be handle, if
        status was wrong case fail.

        :keyword:HalTransport#monitorHandler
        :exception:assertFalse(transport.monitorHandler(msg)),
                   assertFalse(transport.monitorHandler(msg)),
                   assertFalse(transport.monitorHandler(msg)),
                   assertFalse(transport.monitorHandler(msg))
        :parameter:
        :return:

        """
        transport = HalTransport(
            HalTransport.HalTransportClientMgr, HalTransport.HalServerMode,
            disconnectHandlerCb=None)

        msg = {
            "event": zmq.EVENT_DISCONNECTED,
        }
        self.assertFalse(transport.monitorHandler(msg))
        transport.socket.disable_monitor()
        transport.monitor.close()
        transport.close()

        transport = HalTransport(
            HalTransport.HalTransportClientMgr, HalTransport.HalServerMode,
            disconnectHandlerCb=self._disconnectCb)
        self.assertTrue(transport.monitorHandler(msg))

        msg = {
            "event": zmq.EVENT_CONNECT_RETRIED,
        }
        self.assertFalse(transport.monitorHandler(msg))
        time.sleep(transport.socketLogTimeout)
        self.assertTrue(transport.monitorHandler(msg))

        transport.socket.disable_monitor()
        transport.monitor.close()
        transport.close()

        transport = HalTransport(
            HalTransport.HalTransportClientMgr, HalTransport.HalServerMode,
            disconnectHandlerCb=self._disconnectCb)
        msg = {
            "event": zmq.EVENT_CLOSED,
        }
        self.assertFalse(transport.monitorHandler(msg))
        time.sleep(transport.socketLogTimeout)
        self.assertTrue(transport.monitorHandler(msg))

        msg = {
            "event": 10001,
        }
        self.assertFalse(transport.monitorHandler(msg))

        transport.socket.disable_monitor()
        transport.monitor.close()
        transport.close()
示例#4
0
class FaultManagementClient(HalDriverClient):
    """
    refactor the class for fault management
    """
    __metaclass__ = AddLoggerToClass

    RESET_LOG = {
        "PENDING": 1,
        "LOCAL": 2,
    }

    EVENT_VER = '0.0.1'
    event_buffered_local_file = "/tmp/fault_local_%s.json" % EVENT_VER
    event_buffered_pending_file = "/tmp/fault_pending_%s.json" % EVENT_VER

    def __init__(self,
                 appName,
                 appDesc,
                 appVer,
                 disp,
                 supportedMsgType,
                 supportedNotificationMsgs,
                 interestedNotification=None,
                 send_cb=None):

        super(FaultManagementClient,
              self).__init__(appName, appDesc, appVer, supportedMsgType,
                             supportedNotificationMsgs, interestedNotification)
        self.operational = False

        self.dispatcher = disp
        self.send_ntf = send_cb
        self.poll_local_flag = False
        self.poll_pending_flag = False
        self.config_refreshed = False

        self.HalConfigMsgHandlers = {
            MsgTypeRpdGlobal: self.set_global_conf,
            MsgTypetEventNotification: self.read_notification_handler,
            MsgTypeRpdCtrl: self.reset_rpd_log,
        }
        self.HalNotificationMsgHandler = {
            MsgTypeSetLed: self.set_operational_mode,
        }
        rpd_event_def.RpdEventConfig.init_config()

    def set_global_conf(self, cfg):
        """set event global configuration default value."""

        config_data = t_RcpMessage()
        config_data.ParseFromString(cfg.msg.CfgMsgPayload)
        config = config_data.RpdDataMessage.RpdData
        self.logger.debug("Recv global event configuration message, %s" %
                          config)
        rpd_event_def.RpdEventConfig.set_config(config)
        config_data.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
        cfg.msg.CfgMsgPayload = config_data.SerializeToString()
        self.config_refreshed = True

    def read_notification_handler(self, cfg):
        """CCAP core pull operation."""

        config_data = t_RcpMessage()
        config_data.ParseFromString(cfg.msg.CfgMsgPayload)
        config = config_data.RpdDataMessage.RpdData
        self.logger.debug("Recv read request message, %s" % config_data)

        # prepare the response
        rsp_data = t_RcpMessage()
        rsp_data.RcpMessageType = config_data.RcpMessageType
        rsp_data.RpdDataMessage.RpdDataOperation = config_data.RpdDataMessage.RpdDataOperation

        read_count = None
        if config.HasField("ReadCount"):
            read_count = config.ReadCount

        # go through all requests and create the appropriate response
        for notify_req in config.EventNotification:
            # according to the spec the PendingOrLocalLog TLV must be set
            if notify_req.HasField("PendingOrLocalLog"):
                if notify_req.PendingOrLocalLog:
                    buffered = rpd_event_def.EventCommonOperation.BUFFERED_LOCAL
                else:
                    buffered = rpd_event_def.EventCommonOperation.BUFFERED_PENDING

                idx = None
                if notify_req.HasField("RpdEvLogIndex"):
                    idx = notify_req.RpdEvLogIndex
                    if read_count is None:
                        read_count = 1
                else:
                    idx = 0

                evtNtfs = self.read_events(buffered, idx, read_count)

                if evtNtfs:
                    for evt in evtNtfs:
                        newEvt = rsp_data.RpdDataMessage.RpdData.EventNotification.add(
                        )
                        newEvt.CopyFrom(evt)
                else:
                    # no events found return an empty event notification with the
                    # required fields set
                    newEvt = rsp_data.RpdDataMessage.RpdData.EventNotification.add(
                    )
                    newEvt.PendingOrLocalLog = notify_req.PendingOrLocalLog
                    newEvt.RpdEvLogIndex = idx
            else:
                # return the request content
                # Note: The default value for EvFirstTime and EvLastTime
                # is automatically set to R_Dummy, which is wrong for that data
                # type - so set 1970-1-1T00:00:00.0+0:00 as value
                newEvt = rsp_data.RpdDataMessage.RpdData.EventNotification.add(
                )
                newEvt.CopyFrom(notify_req)
                if newEvt.HasField(
                        "EvFirstTime") and newEvt.EvFirstTime == 'R_Dummy':
                    newEvt.EvFirstTime = utils.Convert.pack_timestamp_to_string(
                        0)
                if newEvt.HasField(
                        "EvLastTime") and newEvt.EvLastTime == 'R_Dummy':
                    newEvt.EvFirstTime = utils.Convert.pack_timestamp_to_string(
                        0)

        rsp_data.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
        cfg.msg.CfgMsgPayload = rsp_data.SerializeToString()

    def read_events(self, buffered, idx, rdCnt):
        """ Read events from the pending queue or local log """

        evtNtfList = []
        evts = rpd_event_def.EventCommonOperation.read_log(buffered)

        # calculate the number of elements to read;
        # if the index is not set, then treat it as 0
        numElements = len(evts)
        if rdCnt is None:
            rdCnt = numElements
        elif rdCnt > (numElements - idx):
            rdCnt = numElements - idx

        keys = evts.keys()[idx:(idx + rdCnt)]
        for entry in keys:
            event, msg = evts[entry]
            text = msg['text']

            evtNtfEntry = t_EventNotification()
            evtNtfEntry.RpdEvLogIndex = idx
            idx += 1
            evtNtfEntry.PendingOrLocalLog = msg['PENDING_LOCAL']
            evtNtfEntry.EvFirstTime = utils.Convert.pack_timestamp_to_string(
                int(msg['FirstTime']))
            evtNtfEntry.EvLastTime = utils.Convert.pack_timestamp_to_string(
                int(msg['LastTime']))
            evtNtfEntry.EvCounts = msg['Counts']
            evtNtfEntry.EvLevel = msg['Level']
            evtNtfEntry.EvId = int(event)
            evtNtfEntry.EvString = text.strip()
            evtNtfList.append(evtNtfEntry)

            evts.pop(entry)

        if len(evts):
            rpd_event_def.EventCommonOperation.write_log(evts, buffered)

        return evtNtfList

    def clear_rpd_log(self, reset_log):
        if reset_log & self.RESET_LOG["PENDING"]:
            if os.path.exists(self.event_buffered_pending_file):
                os.remove(self.event_buffered_pending_file)

        if reset_log & self.RESET_LOG["LOCAL"]:
            if os.path.exists(self.event_buffered_local_file):
                os.remove(self.event_buffered_local_file)

    def reset_rpd_log(self, cfg):
        """reset rpd pending and local log."""

        rcp_msg = t_RcpMessage()
        rcp_msg.ParseFromString(cfg.msg.CfgMsgPayload)
        if rcp_msg is None:
            return {
                "Status": HalCommon_pb2.FAILED,
                "ErrorDescription": "DeSerialize ConfigMsgPayload fail"
            }

        recv_rcp_msg = rcp_msg.RpdDataMessage.RpdData
        if recv_rcp_msg.HasField("RpdCtrl") and recv_rcp_msg.RpdCtrl.HasField(
                "LogCtrl"):
            if rcp_msg.RpdDataMessage.RpdDataOperation == t_RpdDataMessage.RPD_CFG_WRITE:
                ctrl_log = recv_rcp_msg.RpdCtrl.LogCtrl
                reset_log = ctrl_log.ResetLog
                self.clear_rpd_log(reset_log)
                rcp_msg.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
                cfg.msg.CfgMsgPayload = rcp_msg.SerializeToString()
                return {
                    "Status": HalCommon_pb2.SUCCESS,
                    "ErrorDescription": "Get Rpd Control success"
                }
            elif rcp_msg.RpdDataMessage.RpdDataOperation == t_RpdDataMessage.RPD_CFG_READ:
                return {
                    "Status":
                    HalCommon_pb2.SUCCESS_IGNORE_RESULT,
                    "ErrorDescription":
                    "Operation %d for Rpd Log Control Can Be Ignored" %
                    rcp_msg.RpdDataMessage.RpdDataOperation
                }
            else:
                return {
                    "Status":
                    HalCommon_pb2.FAILED,
                    "ErrorDescription":
                    "Operation %d for LogCtrl is not supported" %
                    rcp_msg.RpdDataMessage.RpdDataOperation
                }
        else:
            return {
                "Status": HalCommon_pb2.SUCCESS_IGNORE_RESULT,
                "ErrorDescription": "Rcp Msg Do Not Have RpdCtrl Field"
            }

    def set_operational_mode(self, cfg):
        """use set led msg to figure system operational status."""

        led_msg = t_LED()
        led_msg.ParseFromString(cfg)
        self.logger.debug("Set operational msg %s" % str(led_msg))
        action = led_msg.setLed.action
        if action == led_msg.LED_ACTION_LIT and led_msg.setLed.ledType == led_msg.LED_TYPE_STATUS \
                and not self.operational:
            self.operational = True
        elif action == led_msg.LED_ACTION_DARK and led_msg.setLed.ledType == led_msg.LED_TYPE_STATUS \
                and self.operational:
            self.operational = False

    def process_notification_msg(self, cfg):
        """process notification msg."""

        ntf_msg = cfg.msg
        msg_type = ntf_msg.HalNotificationType
        if msg_type not in self.HalNotificationMsgHandler or self.HalNotificationMsgHandler[
                msg_type] is None:
            self.logger.error("msgType %d is not supported" % msg_type)
            return
        self.HalNotificationMsgHandler[msg_type](
            ntf_msg.HalNotificationPayLoad)

    def start(self):
        """Connection setup.

        :return:

        """

        self.logger.debug("Start the client setup...")
        self.connection_setup()
        self.register(self.drvID)

    def connection_setup(self):
        """Create the connection to the mgr and setup the poller.

        :return:

        """

        self.logger.debug("Create the connection to the mgr....")
        # Create a connection to Hal driver mgr
        self.mgrConnection = HalTransport(
            HalTransport.HalTransportClientMgr,
            HalTransport.HalClientMode,
            disconnectHandlerCb=self.connectionDisconnectCb)

        # create the poller
        if self.poller is None:
            self.poller = self.dispatcher.get_poll()

        # register the mgr socket
        self.dispatcher.fd_register(self.mgrConnection.socket,
                                    self.dispatcher.EV_FD_IN,
                                    self.fault_management_cb)
        self.dispatcher.fd_register(self.mgrConnection.monitor,
                                    self.dispatcher.EV_FD_IN,
                                    self.fault_management_cb)

    def recvRegisterMsgCb(self, cfg):  # pragma: no cover
        """The callback handler for the configuration message.

        :param cfg: the configuration message received frm the Hal
        :return:

        """

        # self.logger.debug("Recv a Message from the Hal:" % str(cfg.msg))

        if cfg.msg.Rsp.Status != HalCommon_pb2.SUCCESS:
            self.logger.error("Cannot register to Hal, reason[%s]",
                              cfg.msg.Rsp.ErrorDescription)
            return

        self.drvID = cfg.msg.ClientID

        # Setup the push and pull connection
        self.pullPath = cfg.msg.PathFromHalToClient
        self.pushPath = cfg.msg.PathFromClientToHal

        # get the index of the path
        index = self._getIndexFromPath()
        if index == -1:
            self.logger.error("Cannot get index from the path [%s]" %
                              self.pushPath)
            return
        if self.index == -1:
            self.index = index
            self.pushSock = HalTransport(
                HalTransport.HalTransportClientAgentPull,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPushMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            self.pullSock = HalTransport(
                HalTransport.HalTransportClientAgentPush,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPullMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            # register to the poller
            self.dispatcher.fd_register(self.pullSock.socket, zmq.POLLIN,
                                        self.fault_management_cb)
            self.dispatcher.fd_register(self.pushSock.monitor, zmq.POLLIN,
                                        self.fault_management_cb)
            self.dispatcher.fd_register(self.pullSock.monitor, zmq.POLLIN,
                                        self.fault_management_cb)
        # send Hello To Hal
        self.sayHelloToHal()
        if self.interestedNotification is not None:
            self.sendInterestedNotifications(self.interestedNotification)

        self.disconnected = False

        return

    def fault_management_cb(self, sock, mask):  # pragma: no cover
        """Fault management callback.

        :param sock: zmq socket
        :param mask: event mask
        :return:

        """

        if self.pushSock is not None and sock == self.pushSock.monitor:
            self.pushSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.pullSock is not None and sock == self.pullSock.monitor:
            self.pullSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.mgrConnection is not None and sock == self.mgrConnection.monitor:
            self.mgrConnection.monitorHandler(recv_monitor_message(sock))
            return

        while sock.getsockopt(zmq.EVENTS) and zmq.POLLIN:
            try:
                bin = sock.recv(flags=zmq.NOBLOCK)
                msg = HalMessage.DeSerialize(bin)
                self.logger.debug("###########Got a zmq msg:%s" % msg.msg)
                if msg.type in self.HalMsgsHandler:
                    handler = self.HalMsgsHandler[msg.type]
                    handler(msg)
            except zmq.ZMQError as e:
                self.logger.debug(
                    "Getting an error when trying with nonblock read:" +
                    str(e))
                break
            except Exception as e:
                self.logger.error("Error happens, reason:%s" % str(e))
                break

    def recvCfgMsgCb(self, cfg):
        """Receive a configuration message from the Hal, processing it.

        :param cfg:
        :return:

        """
        try:
            handler = self.HalConfigMsgHandlers[cfg.msg.CfgMsgType]
            handler(cfg)
            self.logger.debug(
                "Recv a configuration message, send the rsp to it")
            self.sendCfgRspMsg(cfg)
        except Exception as e:
            self.logger.error("Got an error:%s, the cfg msg:%s", str(e),
                              cfg.msg)

    def recvNotificationCb(self, msg):
        """
        Receive a configuration message from the Hal, processing it
        :param msg:
        :return:
        """

        self.logger.debug("Recv a notification message\n%s", str(msg.msg))
        self.process_notification_msg(msg)
示例#5
0
class HalPtpClient(HalClient):
    """The PTP Client for Hal."""
    SYNC = "ALIGNED"
    LOS = "LOSS OF SYNC"

    __metaclass__ = AddLoggerToClass

    def __init__(self,
                 appName,
                 appDesc,
                 appVer,
                 supportedNotification,
                 supportedMsgsTypes,
                 dispatcher,
                 notifyCb,
                 logConfigurePath=None):

        # sanity check the input args
        super(HalPtpClient,
              self).__init__(appName, appDesc, appVer, supportedNotification,
                             logConfigurePath, supportedMsgsTypes)

        if not isinstance(supportedNotification, tuple) and not isinstance(
                supportedNotification, list):
            raise HalClientError(
                "supportedMsgsTypes should be a tuple or list")

        self.HalMsgsHandler = {
            "HalClientRegisterRsp": self.recvRegisterMsgCb,
            "HalSetLoggingLevelRsp": self.recvHalSetLoggingLevelRspCb,
            "HalClientHelloRsp": self.recvHelloRspMsgCb,
            "HalConfigRsp": self.recvCfgMsgRspCb,
            "HalClientInterestNotificationCfgRsp":
            self.sendInterestedNotificationsRspCb,
            "HalNotification": self.recvNotificationCb,
            "HalConfig": self.recvCfgMsgCb,
        }

        self.notifyHandler = notifyCb
        self.dispatcher = dispatcher
        self.supportedNotificationMsgs = list(supportedNotification)
        self.dispatcher.timer_register(1, self.checkPtpStatus, timer_type=1)
        self.ptp_result = t_GeneralNotification.PTPACQUIRE

    def checkPtpStatus(self, fd):
        self.sendCfgMsg(MsgTypePtpStatusGet, "GetPtpStatus")

    def start(self):
        """Start polling the transport socket."""
        self.logger.debug("Start the client poll...")
        self.connectionSetup(self.dispatcher)
        self.register(self.clientID)

    def connectionSetup(self, disp=None):
        """Create the connection to the mgr and setup the poller."""
        self.logger.debug("Create the connection to the mgr....")
        # Create a connection to Hal driver mgr
        self.mgrConnection = HalTransport(
            HalTransport.HalTransportClientMgr,
            HalTransport.HalClientMode,
            disconnectHandlerCb=self.connectionDisconnectCb)
        # register the mgr socket
        disp.fd_register(self.mgrConnection.socket, zmq.POLLIN,
                         self.ptp_hal_cb)
        disp.fd_register(self.mgrConnection.monitor, zmq.POLLIN,
                         self.ptp_hal_cb)

    def connectionDisconnectCb(self, msg):
        """The connection has been detected disconnected , register it again
        We have reconenct, we have to assure the regiter message is received
        by the HAL.

        :param msg:
        :return:

        """
        if self.disconnected:
            self.logger.debug("A previous event has been processed, skip it!")
            return
        self.logger.debug("Detected disconnected, register again")
        # clean up the push and pull socket
        if 1:
            self.pushSock.close()
            self.pullSock.close()

            self.dispatcher.fd_unregister(self.pullSock.socket)
            self.dispatcher.fd_unregister(self.pullSock.monitor)
            self.dispatcher.fd_unregister(self.pullSock.monitor)

            self.pushSock = None
            self.pullSock = None
            self.mgrConnection = None
            # self.clientID = None #will not set it to none since

            self.connectionSetup(self.dispatcher)

    def recvRegisterMsgCb(self, cfg):
        """The callback handler for the configuration message.

        :param cfg: the configuration message received frm the Hal
        :return:

        """
        # self.logger.debug("Recv a Message from the Hal:" % str(cfg.msg))

        if cfg.msg.Rsp.Status != HalCommon_pb2.SUCCESS:
            self.logger.error("Cannot register to Hal, reason[%s]" %
                              cfg.msg.Rsp.ErrorDescription)
            return

        self.clientID = cfg.msg.ClientID

        # Setup the push and pull connection
        self.pullPath = cfg.msg.PathFromHalToClient
        self.pushPath = cfg.msg.PathFromClientToHal

        # get the index of the path
        index = self._getIndexFromPath()
        if index == -1:
            self.logger.error("Cannot get index from the path [%s]" %
                              self.pushPath)
            return
        if self.index == -1:
            self.index = index
            self.pushSock = HalTransport(
                HalTransport.HalTransportClientAgentPull,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPushMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            self.pullSock = HalTransport(
                HalTransport.HalTransportClientAgentPush,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPullMode,
                disconnectHandlerCb=self.connectionDisconnectCb)
            # register to the poller
            self.dispatcher.fd_register(self.pullSock.socket, zmq.POLLIN,
                                        self.ptp_hal_cb)
            self.dispatcher.fd_register(self.pushSock.monitor, zmq.POLLIN,
                                        self.ptp_hal_cb)
            self.dispatcher.fd_register(self.pullSock.monitor, zmq.POLLIN,
                                        self.ptp_hal_cb)
        # send Hello To Hal
        self.sayHelloToHal()
        self.sendInterestedNotifications(self.interestedNotification)
        self.disconnected = False

        return

    def recvCfgMsgCb(self, cfgMsg):
        """Receive a configuration message from the Hal, processing it.

        :param cfgMsg:
        :return:

        """
        try:
            msgType = cfgMsg.msg.CfgMsgType
            if msgType == MsgTypeRpdState:
                self.getRpdPtpState(cfgMsg)
        except Exception as e:  # pragma: no cover
            self.logger.error("Got an error:%s, the cfg msg:%s", str(e),
                              cfgMsg)
            rsp = {
                "Status":
                HalCommon_pb2.FAILED,
                "ErrorDescription":
                "Process configuration failed, reason:%s" % str(e)
            }
            self.sendCfgRspMsg(cfgMsg, rsp)

    def recvCfgMsgRspCb(self, cfg):
        """Receive a configuration response message from the Hal, processing it.

        :param cfg:
        :return:

        """
        self.logger.debug("Recv a ptp configuration response message:" +
                          str(cfg.msg))

        if cfg.msg.CfgMsgType == MsgTypePtpStatusGet:
            if cfg.msg.CfgMsgPayload in [self.LOS, self.SYNC]:
                self.notifyHandler(cfg.msg.CfgMsgPayload)
                self.logger.debug("send %s notification to provision",
                                  cfg.msg.CfgMsgPayload)

    def ptp_hal_cb(self, sock, mask):
        if self.pushSock is not None and sock == self.pushSock.monitor:
            self.pushSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.pullSock is not None and sock == self.pullSock.monitor:
            self.pullSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.mgrConnection is not None and sock == self.mgrConnection.monitor:
            self.mgrConnection.monitorHandler(recv_monitor_message(sock))
            return

        while sock.getsockopt(zmq.EVENTS) and zmq.POLLIN:
            try:
                bin = sock.recv(flags=zmq.NOBLOCK)
                msg = HalMessage.DeSerialize(bin)
                self.logger.debug("###########Got a zmq msg:%s" % msg.msg)
                if msg.type in self.HalMsgsHandler:
                    handler = self.HalMsgsHandler[msg.type]
                    handler(msg)
            except zmq.ZMQError as e:
                self.logger.debug(
                    "Geting an error when trying with nonblock read:" + str(e))
                break
            except Exception as e:
                self.logger.error("Error happens, reason:%s" % str(e))
                break

    def recvNotificationCb(self, msg):
        """Receive the notification from ptp hal driver.

        :param msg:
        :return:

        """
        self.logger.info("recv the notification from ptp driver")
        print msg.msg.HalNotificationType
        print msg.msg.HalNotificationPayLoad
        if msg.msg.HalNotificationType == MsgTypePtpClockStatus:
            if msg.msg.HalNotificationPayLoad in [self.LOS, self.SYNC]:
                self.notifyHandler(msg.msg.HalNotificationPayLoad)
                print "send %s notification to provision" % msg.msg.HalNotificationPayLoad

    def getRpdPtpState(self, cfg):
        rsp = t_RcpMessage()
        rsp.ParseFromString(cfg.msg.CfgMsgPayload)
        config = rsp.RpdDataMessage.RpdData
        try:
            config.RpdState.LocalPtpSyncStatus = \
                True if self.ptp_result == t_GeneralNotification.PTPSYNCHRONIZED else False
            cfg.CfgMsgPayload = config.SerializeToString()
            rsp.RpdDataMessage.RpdData.CopyFrom(config)
            rsp.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
            payload = rsp.SerializeToString()
            self.logger.info("Send rpd state LocalPtpSyncStatus response, %s" %
                             rsp)
            msg = HalMessage("HalConfigRsp",
                             SrcClientID=cfg.msg.SrcClientID,
                             SeqNum=cfg.msg.SeqNum,
                             Rsp={
                                 "Status":
                                 HalCommon_pb2.SUCCESS,
                                 "ErrorDescription":
                                 "PTP LOCALPTPSYNCSTATUS query success"
                             },
                             CfgMsgType=cfg.msg.CfgMsgType,
                             CfgMsgPayload=payload)
            self.pushSock.send(msg.Serialize())
        except Exception as e:
            self.logger.error("excpetipn:%s", str(e))
        return
示例#6
0
class RpdResHalClient(HalDriverClient):

    __metaclass__ = AddLoggerToClass

    def __init__(self,
                 appName,
                 appDesc,
                 appVer,
                 disp,
                 supportedMsgType,
                 supportedNotificationMsgs,
                 interestedNotification=None,
                 send_cb=None):

        super(RpdResHalClient,
              self).__init__(appName, appDesc, appVer, supportedMsgType,
                             supportedNotificationMsgs, interestedNotification)
        self.operational = False

        self.dispatcher = disp

        self.HalConfigMsgHandlers = {
            MsgTypeHostResources: self.processHostCfgMsg,
            MsgTypeRpdCtrl: self.processRpdCtrlCfgMsg,
        }
        self.crashFileCtrlHandler = CrashFileCtrlHandler()
        self.hostResourceHandler = HostResourceHandler()

    def processRpdCtrlCfgMsg(self, cfgMsg):
        rcp_msg = t_RcpMessage()
        rcp_msg.ParseFromString(cfgMsg.msg.CfgMsgPayload)
        status = HalCommon_pb2.SUCCESS_IGNORE_RESULT

        recv_rcp_msg = rcp_msg.RpdDataMessage.RpdData
        if recv_rcp_msg.HasField("RpdCtrl"):
            rpdCtrl = recv_rcp_msg.RpdCtrl
            op = rcp_msg.RpdDataMessage.RpdDataOperation
            rcp_msg.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
            flag = False
            if rpdCtrl.HasField("CrashDataServerCtrl"):
                status = HalCommon_pb2.SUCCESS
                self.logger.debug("Recv an RpdCtrlCfgMsg op %d, %s:" %
                                  (op, rpdCtrl))
                if op == t_RpdDataMessage.RPD_CFG_WRITE:
                    self.crashFileCtrlHandler.save_crash_data_server(
                        rpdCtrl.CrashDataServerCtrl)
                    flag = True
                if op == t_RpdDataMessage.RPD_CFG_READ:
                    self.crashFileCtrlHandler.get_crash_data_server(
                        rpdCtrl.CrashDataServerCtrl)
                    flag = True
            if len(rpdCtrl.CrashDataFileCtrl
                   ) > 0 and op == t_RpdDataMessage.RPD_CFG_WRITE:
                flag = True
                index = 0
                for crashDataCtrl in rpdCtrl.CrashDataFileCtrl:
                    if crashDataCtrl.HasField("Index"):
                        index = crashDataCtrl.Index
                    else:
                        rcp_msg.RcpDataResult = t_RcpMessage.RCP_RESULT_GENERAL_ERROR
                    if crashDataCtrl.HasField("FileControl"):
                        fileControl = crashDataCtrl.FileControl
                        if not self.crashFileCtrlHandler.update_pending_file_idx_list(
                                index, fileControl):
                            status = HalCommon_pb2.FAILED
                            rcp_msg.RcpDataResult = t_RcpMessage.RCP_RESULT_GENERAL_ERROR
            if not flag:
                status = HalCommon_pb2.SUCCESS_IGNORE_RESULT
            else:
                status = HalCommon_pb2.SUCCESS
        elif rcp_msg.RpdDataMessage.RpdDataOperation == t_RpdDataMessage.RPD_CFG_READ:
            status = HalCommon_pb2.SUCCESS_IGNORE_RESULT
        else:
            status = HalCommon_pb2.FAILED
        payload = rcp_msg.SerializeToString()
        msg = HalMessage("HalConfigRsp",
                         SrcClientID=cfgMsg.msg.SrcClientID,
                         SeqNum=cfgMsg.msg.SeqNum,
                         Rsp={
                             "Status": status,
                             "ErrorDescription": "Get Rpd Control rsp"
                         },
                         CfgMsgType=cfgMsg.msg.CfgMsgType,
                         CfgMsgPayload=payload)
        return msg

    def processHostCfgMsg(self, cfgMsg):
        rsp = t_RcpMessage()
        # rsp.ParseFromString(cfgMsg.CfgMsgPayload)
        req = t_RcpMessage()
        req.ParseFromString(cfgMsg.msg.CfgMsgPayload)

        rsp.RpdDataMessage.RpdDataOperation = req.RpdDataMessage.RpdDataOperation
        rsp.RcpMessageType = req.RcpMessageType

        # load the rpd host resources information
        hr = rsp.RpdDataMessage.RpdData.HostResources
        hr.hrMemorySize = self.hostResourceHandler.getMemorySize()
        hr.hrProcessorLoad = self.hostResourceHandler.getProcessorLoad()
        self.hostResourceHandler.getStorages(hr.hrStorages)
        self.hostResourceHandler.getProcesses(hr.hrProcesses)

        rsp.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
        payload = rsp.SerializeToString()

        msg = HalMessage("HalConfigRsp",
                         SrcClientID=cfgMsg.msg.SrcClientID,
                         SeqNum=cfgMsg.msg.SeqNum,
                         Rsp={
                             "Status": HalCommon_pb2.SUCCESS,
                             "ErrorDescription": "Host Resource"
                         },
                         CfgMsgType=cfgMsg.msg.CfgMsgType,
                         CfgMsgPayload=payload)
        return msg

    def start(self):
        """Connection setup.

        :return:

        """

        self.logger.debug("Start the client setup...")
        self.connection_setup()
        self.register(self.drvID)

    def connection_setup(self):
        """Create the connection to the mgr and setup the poller.

        :return:

        """

        self.logger.debug("Create the connection to the mgr....")
        # Create a connection to Hal driver mgr
        self.mgrConnection = HalTransport(
            HalTransport.HalTransportClientMgr,
            HalTransport.HalClientMode,
            disconnectHandlerCb=self.connectionDisconnectCb)

        # create the poller
        if self.poller is None:
            self.poller = self.dispatcher.get_poll()

        # register the mgr socket
        self.dispatcher.fd_register(self.mgrConnection.socket,
                                    self.dispatcher.EV_FD_IN,
                                    self.host_management_cb)
        self.dispatcher.fd_register(self.mgrConnection.monitor,
                                    self.dispatcher.EV_FD_IN,
                                    self.host_management_cb)

    def recvRegisterMsgCb(self, cfg):
        """The callback handler for the configuration message.

        :param cfg: the configuration message received frm the Hal
        :return:

        """
        if cfg.msg.Rsp.Status != HalCommon_pb2.SUCCESS:
            self.logger.error("Cannot register to Hal, reason[%s]",
                              cfg.msg.Rsp.ErrorDescription)
            return

        self.drvID = cfg.msg.ClientID
        self.pullPath = cfg.msg.PathFromHalToClient
        self.pushPath = cfg.msg.PathFromClientToHal

        index = self._getIndexFromPath()
        if index == -1:
            self.logger.error("Cannot get index from the path [%s]" %
                              self.pushPath)
            return
        if self.index == -1:
            self.index = index
            self.pushSock = HalTransport(
                HalTransport.HalTransportClientAgentPull,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPushMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            self.pullSock = HalTransport(
                HalTransport.HalTransportClientAgentPush,
                HalTransport.HalClientMode,
                index=index,
                socketMode=HalTransport.HalSocketPullMode,
                disconnectHandlerCb=self.connectionDisconnectCb)

            # register to the poller
            self.dispatcher.fd_register(self.pullSock.socket, zmq.POLLIN,
                                        self.host_management_cb)
            self.dispatcher.fd_register(self.pushSock.monitor, zmq.POLLIN,
                                        self.host_management_cb)
            self.dispatcher.fd_register(self.pullSock.monitor, zmq.POLLIN,
                                        self.host_management_cb)
        # send Hello To Hal
        self.sayHelloToHal()
        if self.interestedNotification is not None:
            self.sendInterestedNotifications(self.interestedNotification)

        self.disconnected = False

        return

    def host_management_cb(self, sock, mask):
        """

        :param sock: zmq socket
        :param mask: event mask
        :return:

        """
        if self.pushSock is not None and sock == self.pushSock.monitor:
            self.pushSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.pullSock is not None and sock == self.pullSock.monitor:
            self.pullSock.monitorHandler(recv_monitor_message(sock))
            return
        if self.mgrConnection is not None and sock == self.mgrConnection.monitor:
            self.mgrConnection.monitorHandler(recv_monitor_message(sock))
            return

        while sock.getsockopt(zmq.EVENTS) and zmq.POLLIN:
            if not self.hal_message_cb(sock):
                break

    def hal_message_cb(self, sock):
        try:
            bin = sock.recv(flags=zmq.NOBLOCK)
            msg = HalMessage.DeSerialize(bin)
            self.logger.debug("###########Got a zmq msg:%s" % msg.msg)
            if msg.type in self.HalMsgsHandler:
                handler = self.HalMsgsHandler[msg.type]
                handler(msg)
        except zmq.ZMQError as e:
            self.logger.debug(
                "Getting an error when trying with nonblock read:" + str(e))
            return False
        except Exception as e:
            self.logger.error("Error happens, reason:%s" % str(e))
            return False
        return True

    def recvCfgMsgCb(self, cfg):
        """Receive a configuration message from the Hal, processing it.

        :param cfg:
        :return:

        """
        try:
            handler = self.HalConfigMsgHandlers[cfg.msg.CfgMsgType]
            msg = handler(cfg)
            if self.pushSock:
                self.pushSock.send(msg.Serialize())
            self.logger.debug(
                "Recv a configuration message, send the rsp to it")
        except Exception as e:
            self.logger.error("Got an error:%s, the cfg msg:%s", str(e),
                              cfg.msg)