Ejemplo n.º 1
0
    def test_send(self):
        """test HalTransport#send.

        check whether none message can be send, if
        can't catch the specific exception case fail

        check whether hello
        message can be send, if the returned value is false case fail.

        :keyword:HalTransport#send
        :exception:assertRegexpMatches(str(e), "Cannot send the msg since the msg is None, agent.*"),
                   assertEqual(pushSock.send("hello"), True)
        :parameter:
        :return:

        """
        transport = HalTransport(
            HalTransport.HalTransportClientMgr, HalTransport.HalServerMode,
            disconnectHandlerCb=self._disconnectCb)

        try:
            transport.send(None)
        except Exception as e:
            self.assertRegexpMatches(
                str(e), "Cannot send the msg since the msg is None, agent.*")
        transport.socket.disable_monitor()
        transport.monitor.close()
        transport.close()

        pushSock = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalClientMode,
            index=19, socketMode=HalTransport.HalSocketPushMode, disconnectHandlerCb=None)
        self.assertEqual(pushSock.send("hello"), True)

        pushSock.socket.disable_monitor()
        pushSock.monitor.close()
        pushSock.close()
Ejemplo n.º 2
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()
Ejemplo n.º 3
0
class CliHalIpc(object):
    """
    The Client for Hal
    """
    __metaclass__ = AddLoggerToClass

    def __init__(self, appName, appDesc, appVer, interestedNotification, logConfigurePath=None):
        """
        :param appName: The application name, such as RPD CLI
        :param appDesc: A brief description about this application, such as the functionality description
        :param appVer: Driver specific version, such as 1.0.1
        :param interestedNotification: a tuple or list for the application interested msg types, the form will be
                                       (1, 2, 456, 10)
        :return: HalClient object
        """
        # sanity check the input args
        if not isinstance(appName, str) or not isinstance(appDesc, str) or not isinstance(appVer, str):
            raise HalClientError("Driver name/desc/version should be a str type")

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

        self.appName = appName
        self.appDesc = appDesc
        self.appVer = appVer
        self.interestedNotification = list(interestedNotification)

        # setup the logging
        # self.logger = log
        self.pollTimeout = 2000

        # update the supported messages
        self.HalMsgsHandler = {
            "HalClientRegisterRsp": self.recvRegisterMsgCb,
            "HalClientHelloRsp": self.recvHelloRspMsgCb,
            "HalClientInterestNotificationCfgRsp": self.sendInterestedNotificationsRspCb,
        }

        self.clientID = None

        self.mgrConnection = None
        self.pushSock = None
        self.pullSock = None

        self.disconnected = True

        self.seqNum = 0
        self.index = -1
        self.CfgMsgId_dict = dict(CLI_TO_HAL_MSG_TYPE.items())

    def start(self):
        """
        start poll the transport socket
        :return:
        """
        self.logger.debug("Start connect to hal...")
        self.connectionSetup()

        self.register(self.clientID)

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

    def register(self, clientID):
        """
        send a register message to Hal and get the device ID from the Hal.
        :return:
        """
        if clientID is None:
            registerMsg = HalMessage("HalClientRegister",
                                     ClientName=self.appName,
                                     ClientDescription=self.appDesc,
                                     ClientVersion=self.appVer)
        else:
            registerMsg = HalMessage("HalClientRegister",
                                     ClientName=self.appName,
                                     ClientDescription=self.appDesc,
                                     ClientVersion=self.appVer,
                                     ClientID=clientID)

        if self.mgrConnection is None:
            errMsg = "Cannot send the register since the mgr connection is not setup"
            self.logger.error(errMsg)
            raise HalClientError(errMsg)
        self.logger.debug("Send the register msg to Hal...")
        self.mgrConnection.send(registerMsg.Serialize())
        bin = self.mgrConnection.recv()
        rsp = HalMessage.DeSerialize(bin)
        self.recvRegisterMsgCb(rsp)

    def _send(self, msg):
        if self.pushSock:
            self.pushSock.send(msg)
        else:
            self.logger.error("Cannot send the msg since the push socket is NULL")

    def sendMsg(self, cfgMsg):
        """
        The configutaion response routine, the driver implementor should fill
        sth into this function
        :param cfg: The original configutaion message
        :return:
        """
        if self.disconnected:
            self.logger.error("The client is on disconencted state,"
                              " skip to send the message.")
            return

        if cfgMsg is None or not isinstance(cfgMsg, t_CliMessage):
            self.logger.error("Cannot send a None or incorrect type to HAL")
            return

        for desc, value in cfgMsg.CliData.ListFields():
            if desc.name not in self.CfgMsgId_dict:
                self.logger.error("Cannot not find %s" % desc.name)
                return
            msg = HalMessage("HalConfig", SrcClientID=self.clientID,
                             SeqNum=self.seqNum,
                             CfgMsgType=self.CfgMsgId_dict[desc.name],
                             CfgMsgPayload=cfgMsg.SerializeToString())
            self._send(msg.Serialize())

            seq = self.seqNum
            self.seqNum += 1
            return seq

    def recvMsg(self, timeout=None):
        if self.pullSock:
            try:
                bin = self.pullSock.recv()
            except Exception as e:
                print("Got exception when receiving the msg, reason:%s" % str(e))
                return None
            rsp = HalMessage.DeSerialize(bin)
            if rsp.msg.Rsp.Status != HalCommon_pb2.SUCCESS:
                self.logger.error("Get rsp msg fail, reason[%s]" % rsp.msg.Rsp.ErrorDescription)
                return None
            cli_msg = t_CliMessage()
            cli_msg.ParseFromString(rsp.msg.CfgMsgPayload)
            return cli_msg
        else:
            self.logger.error("Cannot receive msg since the pull socket is NULL")
            return None

    def sayHelloToHal(self):
        """
        Send a hello message to verify the agent path is correct
        :return:
        """
        self.logger.debug("Send a Hello message to Hal")
        helloMsg = HalMessage("HalClientHello", ClientID=self.clientID)
        self._send(helloMsg.Serialize())

    def sendInterestedNotifications(self, notifications):
        """
        Send the notifications to the HAL
        :param notifications:
        :return:
        """
        self.logger.debug("Send a Interested notification configuration msg to HAL")
        if notifications is not None and not isinstance(notifications, tuple) and not isinstance(notifications, list):
            self.logger.error("Cannot set an notification with wrong type, you can pass a tuple or list to it ")
            return
        configMsg = HalMessage("HalClientInterestNotificationCfg", ClientID=self.clientID,
                               ClientNotificationMessages=notifications)
        self.mgrConnection.send(configMsg.Serialize())
        # REQ/RSP
        bin = self.mgrConnection.recv()
        return bin

    def sendInterestedNotificationsRspCb(self, rsp):
        """
        Receive a response message from the HAL for the notification rsp callback
        :param rsp:
        :return:
        """
        self.logger.debug("Receive a interest notification response message:" + str(rsp.msg))

    def recvHelloRspMsgCb(self, hello):
        """
        Call back for Hello Message
        :param hello:
        :return:
        """
        self.logger.debug("Recv a hello message:" + str(hello.msg))

    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 0:
            self.pushSock.close()
            self.pullSock.close()

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

            self.connectionSetup()

        self.mgrConnection.monitor.close()
        self.mgrConnection.close()

        # create the connection again
        self.connectionSetup()
        self.register(self.clientID)  # The zmq lower part will handle the reconnect

        self.disconnected = True

    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)

        self.sendInterestedNotifications(self.interestedNotification)

        self.disconnected = False

        return

    def clientQuery(self):
        """
        Send a client query message to get all registered client info
        :return:
        """

        if self.disconnected:
            self.logger.error("The client is on disconencted state,"
                              " skip to send the message.")
            return None
        self.logger.debug("Send a client query message to Hal")
        clientQueryMsg = HalMessage("HalClientQuery", ClientID=self.clientID)
        self.mgrConnection.send(clientQueryMsg.Serialize())
        try:
            bin = self.mgrConnection.recv()
        except Exception as e:
            print("Got exception when receiving the msg, reason:%s" % str(e))
            return None
        rsp = HalMessage.DeSerialize(bin)
        if rsp.msg.MsgType != "HalClientQueryRsp":
            self.logger.error("Cannot Query client, "
                              "reason[msgType mismatch:%s]" % rsp.msg.MsgType)
            return None
        return rsp

    def getClientstats(self, clientId):
        """
        Send a client statistics request message
        :return:
        """

        if self.disconnected:
            self.logger.error("The client is on disconencted state,"
                              " skip to send the message.")
            return None
        self.logger.debug("Send a client statistics message to Hal")
        statsQueryMsg = HalMessage("HalAgentStatsReq", ClientID=clientId)
        self.mgrConnection.send(statsQueryMsg.Serialize())
        try:
            bin = self.mgrConnection.recv()
        except Exception as e:
            print("Got exception when receiving the msg, reason:%s" % str(e))
            return None
        rsp = HalMessage.DeSerialize(bin)
        if rsp.msg.MsgType != "HalAgentStatsRsp":
            self.logger.error("Cannot Query client statistics, "
                              "reason[msgType mismatch:%s]" % rsp.msg.MsgType)
            return None
        return rsp

    def _getIndexFromPath(self):
        rePattern = r"/(\d+)/"
        ret = re.search(rePattern, self.pushPath)

        if ret is not None:
            digitStr = ret.group(1)
            return int(digitStr)

        return -1
Ejemplo n.º 4
0
    registerMsg = HalClientRegister()
    registerMsg.MsgType = "HalClientRegister"
    registerMsg.ClientName = "Test"
    registerMsg.ClientDescription = "This is a test msg"
    registerMsg.ClientVersion = "1.0"
    registerMsg.ClientSupportedMessages.append(1)
    registerMsg.ClientSupportedMessages.append(123)
    registerMsg.ClientSupportedNotificationMessages.append(11)
    registerMsg.ClientSupportedNotificationMessages.append(12)

    strMsg = registerMsg.SerializeToString()

    # dump the message
    hexdump.hexdump(strMsg)
    trans.send(strMsg)
    bin = trans.recv()

    rsp = HalMessage.DeSerialize(bin)

    ClientID = rsp.msg.ClientID

    push = rsp.msg.PathFromHalToClient
    pull = rsp.msg.PathFromClientToHal

    print ClientID
    print pull
    print push

    # Create the Pull interface
    context = HalTransport.context
Ejemplo n.º 5
0
class HalDriverClient(object):
    """The Driver Client for Hal."""

    __metaclass__ = AddLoggerToClass

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

        :param drvName: The driver name, such as BCM3160 Driver
        :param drvDesc: A brief description about this driver, such as the driver main functionality description
        :param drvVer: Driver specific version, such as 1.0.1
        :param supportedMsgType: a tuple or list for the driver supported msg types, the form will be (1, 2, 456, 10)
        :param supportedNotificationMsgs: the driver supported notification msg types the form will be (1, 3, 4)
        :return: HalDriverClient object

        """
        # sanity check the input args
        if not isinstance(drvName, str) or not isinstance(
                drvDesc, str) or not isinstance(drvVer, str):
            raise HalDriverClientError(
                "Driver name/desc/version should be a str type")

        if not isinstance(supportedMsgType, tuple) and not isinstance(
                supportedMsgType, list):
            raise HalDriverClientError(
                "supportedMsgType should be a tuple or list")

        if (supportedNotificationMsgs is not None) and (
                not isinstance(supportedNotificationMsgs, list)
                and not isinstance(supportedNotificationMsgs, tuple)):
            raise HalDriverClientError(
                "supportedNotificationMsgs is allowed none or tuple or list")

        self.drvname = drvName
        self.drvDesc = drvDesc
        self.drvVer = drvVer
        if None is not interestedNotification:
            self.interestedNotification = list(interestedNotification)
        else:
            self.interestedNotification = None
        self.supportedMsgType = list(supportedMsgType)
        if supportedNotificationMsgs is not None:
            self.supportedNotificationMsgs = list(supportedNotificationMsgs)
        else:
            self.supportedNotificationMsgs = None
        self.recvNtf = 0

        self.pollTimeout = 1000

        # update the supported messages
        self.HalMsgsHandler = {
            "HalClientRegisterRsp": self.recvRegisterMsgCb,
            "HalClientHelloRsp": self.recvHelloRspMsgCb,
            "HalConfig": self.recvCfgMsgCb,
            "HalConfigRsp": self.recvCfgMsgRspCb,
            "HalClientInterestNotificationCfgRsp":
            self.sendInterestedNotificationsRspCb,
            "HalNotification": self.recvNotificationCb,
        }

        self.drvID = None

        self.mgrConnection = None
        self.pushSock = None
        self.pullSock = None

        self.pullPath = None
        self.pushPath = None

        self.disconnected = True
        self.poller = None

        self.index = -1
        self.seqNum = 0

    def start(self):
        """Start polling the transport socket.

        :return:

        """
        self.logger.debug("Start the driver client poll...")
        self.connectionSetup()

        self.register(self.drvID)
        lastTimeout = time()

        while True:  # Todo we should support quit flag?
            socks = self.poller.poll(self.pollTimeout)
            if time() - lastTimeout > self.pollTimeout / 1000:
                lastTimeout = time()
                # self.logger.debug("Got a timeout event")
                if self.recvNtf:
                    rcp_msg = t_RcpMessage()
                    rcp_msg.RpdDataMessage.RpdDataOperation = t_RpdDataMessage.RPD_CFG_READ
                    rcp_msg.RcpMessageType = t_RcpMessage.RPD_CONFIGURATION
                    rcp_msg.RpdDataMessage.RpdData.CopyFrom(config())
                    payload = rcp_msg.SerializeToString()
                    self.sendCfgMsg(1025, payload)
                    self.recvNtf -= 1

            if not socks:
                continue
            for sock in socks:
                if self.pushSock is not None and sock == self.pushSock.monitor:
                    self.pushSock.monitorHandler(recv_monitor_message(sock))
                    continue
                if self.pullSock is not None and sock == self.pullSock.monitor:
                    self.pullSock.monitorHandler(recv_monitor_message(sock))
                    continue
                if sock == self.mgrConnection.monitor:
                    self.mgrConnection.monitorHandler(
                        recv_monitor_message(sock))
                    continue
                if socks[sock] == HalPoller.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)
                        else:
                            self.logger.warn("Unsupported msg type:%s" %
                                             msg.type)
                    except zmq.ZMQError as e:
                        self.logger.debug(
                            "Geting an error when trying with nonblock read:" +
                            str(e))
                    except Exception as e:
                        self.logger.debug("Geting an error:" + str(e))
                continue

    def connectionSetup(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)
        self.mgrConnection.connects()

        self.HalMsgsHandler[self.mgrConnection.socket] = self.recvRegisterMsgCb
        # create the poller
        if self.poller is None:
            self.poller = HalPoller()

        # register the mgr socket
        self.poller.register(self.mgrConnection.socket)
        self.poller.register(self.mgrConnection.monitor)

    def register(self, driverID):
        """Send a register message to Hal and get the client ID from the Hal.

        :return:

        """
        if driverID is None:
            registerMsg = HalMessage(
                "HalClientRegister",
                ClientName=self.drvname,
                ClientDescription=self.drvDesc,
                ClientVersion=self.drvVer,
                ClientSupportedMessages=self.supportedMsgType,
                ClientSupportedNotificationMessages=self.
                supportedNotificationMsgs)
        else:
            registerMsg = HalMessage(
                "HalClientRegister",
                ClientName=self.drvname,
                ClientDescription=self.drvDesc,
                ClientVersion=self.drvVer,
                ClientSupportedMessages=self.supportedMsgType,
                ClientSupportedNotificationMessages=self.
                supportedNotificationMsgs,
                ClientID=driverID)

        if self.mgrConnection is None:
            errMsg = "Cannot send the register since the mgr connection is not setup"
            self.logger.error(errMsg)
            raise HalDriverClientError(errMsg)
        self.logger.debug("Send the register msg to Hal...")
        self.mgrConnection.send(registerMsg.Serialize())

    def send(self, msg):
        if self.pushSock:
            self.pushSock.send(msg)
        else:
            self.logger.warning(" ".join([
                str(self.drvname),
                str(self.drvID),
                ":Cannot send the msg since the push socket is none"
            ]))

    def sayHelloToHal(self):
        """Send a hello message to verify the agent path is correct.

        :return:

        """
        self.logger.debug(" ".join([
            str(self.drvname),
            str(self.drvID), ":Send a Hello message to Hal"
        ]))
        helloMsg = HalMessage("HalClientHello", ClientID=self.drvID)
        self.send(helloMsg.Serialize())

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

        :param hello:
        :return:

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

    def sendInterestedNotifications(self, notifications):
        """Send the notifications to the HAL.

        :param notifications:
        :return:

        """
        self.logger.debug(
            "Send a Interested notification configuration msg to HAL")
        if notifications is not None and not isinstance(
                notifications, tuple) and not isinstance(notifications, list):
            self.logger.error(
                "Cannot set an notification with wrong type, you can pass a tuple or list to it "
            )
            return
        configMsg = HalMessage("HalClientInterestNotificationCfg",
                               ClientID=self.drvID,
                               ClientNotificationMessages=notifications)
        self.mgrConnection.send(configMsg.Serialize())

    def sendInterestedNotificationsRspCb(self, rsp):
        """Receive a response message from the HAL for the notification rsp
        callback.

        :param rsp:
        :return:

        """
        self.logger.debug("Receive a interest notification response message:" +
                          str(rsp.msg))

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

        :param ntf:
        :return:

        """
        self.logger.debug("Receive a interest notification message:" +
                          str(ntf.msg))
        self.recvNtf += 1

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

        :param cfg:
        :return:

        """
        self.logger.debug(
            "Recv a configuration message, send a fake rsp to it")
        self.sendCfgRspMsg(cfg)

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

    def connectionSetupCb(self):
        pass

    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")
        # clean up the push and pull socket
        # self.poller.unregister(self.pullSock.socket)

        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.register(self.drvID)
        # The zmq lower part will handle the reconnect

        self.disconnected = True

    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")
        notfication = HalMessage("HalNotification",
                                 ClientID=self.drvID,
                                 HalNotificationType=notificationType,
                                 HalNotificationPayLoad=notificationPayload)
        self.send(notfication.Serialize())

    def sendCfgMsg(self, cfgMsgType, cfgMsgContent):
        """The configutaion response routine, the driver implementor should
        fill sth into this function.

        :param cfg: The original configuration message
        :return:

        """
        self.logger.debug("Send a config message to HAL: %r", cfgMsgContent)

        if self.disconnected:
            self.logger.warn(
                "The client is on disconencted state, skip to send the message."
            )
            return

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

        msg = HalMessage("HalConfig",
                         SrcClientID=self.drvID,
                         SeqNum=self.seqNum,
                         CfgMsgType=cfgMsgType,
                         CfgMsgPayload=cfgMsgContent)
        self._sendMsg(msg.Serialize())

        seq = self.seqNum
        self.seqNum += 1
        return seq

    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

        if rsp == None:
            rsp = {"Status": HalCommon_pb2.SUCCESS, "ErrorDescription": ""}

        msg = HalMessage("HalConfigRsp",
                         SrcClientID=cfgMsg.SrcClientID,
                         SeqNum=cfgMsg.SeqNum,
                         Rsp=rsp,
                         CfgMsgType=cfgMsg.CfgMsgType,
                         CfgMsgPayload=cfgMsg.CfgMsgPayload)
        if None is not self.pushSock:
            self.pushSock.send(msg.Serialize())

    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.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.poller.register(self.pushSock.monitor)
            self.poller.register(self.pullSock.monitor)
            self.poller.register(self.pullSock.socket)

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

        self.disconnected = False

        return

    def _getIndexFromPath(self):
        rePattern = r"/(\d+)/"
        ret = re.search(rePattern, self.pushPath)

        if ret is not None:
            digitStr = ret.group(1)
            return int(digitStr)

        return -1

    def _sendMsg(self, msg):
        if self.pushSock:
            self.pushSock.send(msg)
        else:
            self.logger.error(
                "Cannot send the msg since the push socket is NULL")
Ejemplo n.º 6
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
Ejemplo n.º 7
0
class HalClient(object):
    """The Client for Hal."""

    __metaclass__ = AddLoggerToClass

    def __init__(self,
                 appName,
                 appDesc,
                 appVer,
                 interestedNotification,
                 logConfigurePath=None,
                 supportedMsgType=[]):
        """
        :param appName: The application name, such as RPD CLI
        :param appDesc: A brief description about this application, such as the functionality description
        :param appVer: Driver specific version, such as 1.0.1
        :param interestedNotification: a tuple or list for the application interested msg types, the form will be
                                       (1, 2, 456, 10)
        :param supportedMsgType: a tuple or list of HalConfig message types, the form will be (5000,)
        :return: HalClient object

        """
        # sanity check the input args
        if not isinstance(appName, str) or not isinstance(
                appDesc, str) or not isinstance(appVer, str):
            raise HalClientError(
                "Driver name/desc/version should be a str type")

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

        if not isinstance(supportedMsgType, list):
            raise HalClientError("supportedMsgType should be a list")

        self.appName = appName
        self.appDesc = appDesc
        self.appVer = appVer
        self.interestedNotification = list(interestedNotification)
        self.supportedMsgType = list(supportedMsgType)

        self.pollTimeout = 2000

        # update the supported messages
        self.HalMsgsHandler = {
            "HalClientRegisterRsp":
            self.recvRegisterMsgCb,
            "HalSetLoggingLevelRsp":
            self.recvHalSetLoggingLevelRspCb,
            "HalClientHelloRsp":
            self.recvHelloRspMsgCb,
            "HalConfigRsp":
            self.recvCfgMsgRspCb,
            "HalClientInterestNotificationCfgRsp":
            self.sendInterestedNotificationsRspCb,
        }

        self.clientID = None

        self.mgrConnection = None
        self.pushSock = None
        self.pullSock = None

        self.disconnected = True
        self.poller = None

        self.seqNum = 0
        self.index = -1

    def start(self):
        """Start polling the transport socket.

        :return:

        """
        self.logger.debug("Start the client poll...")
        self.connectionSetup()

        self.register(self.clientID)
        lastTimeout = time()

        sendOnce = False

        while True:  # Todo we should support quit flag?
            socks = self.poller.poll(self.pollTimeout)

            if time() - lastTimeout > self.pollTimeout / 1000:
                lastTimeout = time()
                self.logger.debug("Got a timeout event")
                if not sendOnce:
                    # self.sendCfgMsg(100, "hello")
                    self.setHalDebugLevel("HalMain", logging.INFO)
                    sendOnce = True

            if not socks:
                continue
            for sock in socks:  # FIXME do we need to continue recv from the monitor interface?
                if self.pushSock is not None and sock == self.pushSock.monitor:
                    self.pushSock.monitorHandler(recv_monitor_message(sock))
                    continue
                if self.pullSock is not None and sock == self.pullSock.monitor:
                    self.pullSock.monitorHandler(recv_monitor_message(sock))
                    continue
                if self.mgrConnection is not None and sock == self.mgrConnection.monitor:
                    self.mgrConnection.monitorHandler(
                        recv_monitor_message(sock))
                    continue
                if socks[sock] == HalPoller.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)
                        else:
                            self.logger.warn("Unsupported msg type:%s" %
                                             msg.type)
                    except zmq.ZMQError as e:
                        self.logger.debug(
                            "Got an error when trying with non-block read:" +
                            str(e))
                    except Exception as e:
                        self.logger.error("Error happens, reason:%s" % str(e))
                continue
                # self.logger.error("Cannot handle the event, No handler for
                # it")

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

        self.HalMsgsHandler[self.mgrConnection.socket] = self.recvRegisterMsgCb
        # create the poller
        if self.poller is None:
            self.poller = HalPoller()

        # register the mgr socket
        self.poller.register(self.mgrConnection.socket)
        self.poller.register(self.mgrConnection.monitor)

    def register(self, clientID):
        """Send a register message to Hal and get the client ID from the Hal.

        :return:

        """
        if clientID is None:
            if len(self.supportedMsgType) > 0:
                registerMsg = HalMessage(
                    "HalClientRegister",
                    ClientName=self.appName,
                    ClientDescription=self.appDesc,
                    ClientVersion=self.appVer,
                    ClientSupportedMessages=self.supportedMsgType)
            else:
                registerMsg = HalMessage("HalClientRegister",
                                         ClientName=self.appName,
                                         ClientDescription=self.appDesc,
                                         ClientVersion=self.appVer)
        else:
            if len(self.supportedMsgType) > 0:
                registerMsg = HalMessage(
                    "HalClientRegister",
                    ClientName=self.appName,
                    ClientDescription=self.appDesc,
                    ClientVersion=self.appVer,
                    ClientSupportedMessages=self.supportedMsgType,
                    ClientID=clientID)
            else:
                registerMsg = HalMessage("HalClientRegister",
                                         ClientName=self.appName,
                                         ClientDescription=self.appDesc,
                                         ClientVersion=self.appVer,
                                         ClientID=clientID)

        if self.mgrConnection is None:
            errMsg = "Cannot send the register since the mgr connection is not setup"
            self.logger.error(errMsg)
            raise HalClientError(errMsg)
        self.logger.debug("Send the register msg to Hal...")
        self.mgrConnection.send(registerMsg.Serialize())

    def _sendMsg(self, msg):
        if self.pushSock:
            self.pushSock.send(msg)
        else:
            self.logger.error(
                "Cannot send the msg since the push socket is None, msg:%s",
                str(msg))

    def sayHelloToHal(self):
        """Send a hello message to verify the agent path is correct.

        :return:

        """
        self.logger.debug(" ".join([
            str(self.appName),
            str(self.clientID), ":Send a Hello message to Hal"
        ]))
        helloMsg = HalMessage("HalClientHello", ClientID=self.clientID)
        self._sendMsg(helloMsg.Serialize())

    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 notification message to Hal")
        notfication = HalMessage("HalNotification",
                                 ClientID=self.clientID,
                                 HalNotificationType=notificationType,
                                 HalNotificationPayLoad=notificationPayload)
        self.pushSock.send(notfication.Serialize())

    def sendInterestedNotifications(self, notifications):
        """Send the notifications to the HAL.

        :param notifications:
        :return:

        """
        self.logger.debug(
            "Send a Interested notification configuration msg to HAL")
        if notifications is not None and not isinstance(
                notifications, tuple) and not isinstance(notifications, list):
            self.logger.error(
                "Cannot set an notification with wrong type, you can pass a tuple or list to it "
            )
            return
        configMsg = HalMessage("HalClientInterestNotificationCfg",
                               ClientID=self.clientID,
                               ClientNotificationMessages=notifications)
        self.mgrConnection.send(configMsg.Serialize())

    def sendInterestedNotificationsRspCb(self, rsp):
        """Receive a response message from the HAL for the notification rsp
        callback.

        :param rsp:
        :return:

        """
        self.logger.debug("Receive a interest notification response message:" +
                          str(rsp.msg))

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

        :param hello:
        :return:

        """
        self.logger.debug("Recv a hello message:" + str(hello.msg))

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

    def connectionSetupCb(self):
        pass

    def connectionDisconnectCb(self, msg):
        """TODO: This comment is confusing. Need to be cleaned up.

        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 0:
            self.pushSock.close()
            self.pullSock.close()

            self.poller.unregister(self.pullSock.socket)
            self.poller.unregister(self.pullSock.monitor)
            self.poller.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.poller.unregister(self.mgrConnection.socket)
        self.poller.unregister(self.mgrConnection.monitor)
        self.mgrConnection.socket.disable_monitor()
        self.mgrConnection.monitor.close()
        self.mgrConnection.close()

        # create the connection again
        self.connectionSetup()
        self.register(self.clientID)
        # The zmq lower part will handle the reconnect

        self.disconnected = True

    def sendCfgMsg(self, cfgMsgType, cfgMsgContent):
        """The configutaion response routine, the driver implementor
        should fill sth into this function.

        :param cfg: The original configutaion message
        :return:

        """
        self.logger.debug("Send a config message to HAL: %r", cfgMsgContent)

        if self.disconnected:
            self.logger.warn(
                "The client is on disconnected state, skip to send the message."
            )
            return

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

        msg = HalMessage("HalConfig",
                         SrcClientID=self.clientID,
                         SeqNum=self.seqNum,
                         CfgMsgType=cfgMsgType,
                         CfgMsgPayload=cfgMsgContent)
        self._sendMsg(msg.Serialize())

        seq = self.seqNum
        self.seqNum += 1
        return seq

    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)
        if None is not self.pushSock:
            self.pushSock.send(msg.Serialize())

    def setHalDebugLevel(self, module, level):
        """Set the HAl debug level.

        :param module: the Hal module name
        :param level: the logging level
        :return:

        """
        self.logger.info("Set hal module[%s] to level [%s]" %
                         (module, logging.getLevelName(level)))

        if self.disconnected:
            self.logger.warn("Cannot send the HAL debug configuration to HAL"
                             " since the client is in disconnected  state.")
            return
        msg = HalMessage("HalSetLoggingLevel",
                         ClientID=self.clientID,
                         Module=module,
                         LoggingLevel=level)

        self.mgrConnection.send(msg.Serialize())

    def recvHalSetLoggingLevelRspCb(self, rsp):
        self.logger.debug(str(rsp.msg))

    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.poller.register(self.pullSock.socket)
            self.poller.register(self.pushSock.monitor)
            self.poller.register(self.pullSock.monitor)
        # send Hello To Hal
        self.sayHelloToHal()
        self.sendInterestedNotifications(self.interestedNotification)

        self.disconnected = False

        return

    def _getIndexFromPath(self):
        rePattern = r"/(\d+)/"
        ret = re.search(rePattern, self.pushPath)

        if ret is not None:
            digitStr = ret.group(1)
            return int(digitStr)

        return -1
Ejemplo n.º 8
0
class HalAgentClient(HalAgent):
    """This class is the client agent class.

    the class will have the following API:

    * disconnectHandler:  the
      handler will be invoked when the transport layer get a disconnect
      event, the function will clean the agent
      resources, including the socket resource, remove it from the global
      runtime DB.
    * sendMsg: This API will send message via
      Agent's pushsock channel.
    * handleClientHello: The API will handle
      the Hello message
    * handleConfigRsp: This API will handle the
      configuration response HalMessage from client
    * handleNotification: This API will handle the notification HalMessage

    """
    ClientIndex = 0
    # self handle table
    HalGlobal.gHandleTable["HalClientHello"] = "handleClientHello"
    HalGlobal.gHandleTable["HalConfig"] = "handleConfig"
    HalGlobal.gHandleTable["HalConfigRsp"] = "handleConfigRsp"
    HalGlobal.gHandleTable["HalNotification"] = "handleNotification"

    __metaclass__ = AddLoggerToClass

    def __init__(self, poller, clientID, disconnectHandler, reuseIndex=None):
        """The function will generate the client agent object. the main
        function is to create the socket channel. for Hal the sock channel
        works at the server mode, it will listen at these sockets.

        :param poller: a global poller, the transport socket and the monitor socket will register into it.
        :param ClientID: a client  UUID
        :param disconnectHandler: the manager disconnect handler, will be called with agent gets a disconnect event.
        :param reuseIndex: for the client restart, it will provide it's previous ID, the agent will reuse
                            these ID and use the same transport path.
        :return: agent obj

        """
        super(HalAgentClient, self).__init__()

        if reuseIndex is None:
            # Generate the client index
            while True:
                index = HalAgentClient.ClientIndex
                HalAgentClient.ClientIndex += 1
                if str(index) not in HalGlobal.gClientIndex.values():
                    break
        else:
            index = reuseIndex

        self.index = index

        if clientID not in HalGlobal.gClientIndex:
            HalGlobal.gHalClientDbConnection.addMsgtoDB(
                "ClientIndex", {clientID: index}, expired=False)

        # Start the transport
        self.transportPush = HalTransport(
            HalTransport.HalTransportClientAgentPush, HalTransport.HalServerMode,
            index=index, socketMode=HalTransport.HalSocketPushMode,
            disconnectHandlerCb=self.disconnectHandler)

        # for the push, we don't need to register to the poller

        if self.transportPush.monitor:
            poller.register(self.transportPush.monitor)
            HalGlobal.gMonitorSocketMappingTable[
                self.transportPush.monitor] = self.transportPush

        # start the pull transport
        self.transportPull = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalServerMode,
            index=index, socketMode=HalTransport.HalSocketPullMode,
            disconnectHandlerCb=self.disconnectHandler)
        poller.register(self.transportPull.socket)
        # add the pull socket to the socket agent mapping table
        HalGlobal.gSocketAgentMappingTable[self.transportPull.socket] = self

        # process the monitor
        if self.transportPull.monitor:
            poller.register(self.transportPull.monitor)
            HalGlobal.gMonitorSocketMappingTable[
                self.transportPull.monitor] = self.transportPull

        # For other variables
        self.mgrDisconnectCb = disconnectHandler
        self.disconnectProcessed = False
        self.poller = poller
        self.clientID = clientID

        # put the message into the resend list
        self.logger.debug("Check the last unsuccessful message.%s for client[%s]" % (
            HalGlobal.gRestartResendMsg, self.clientID))
        if self.clientID:
            for key in HalGlobal.gRestartResendMsg:
                if key.startswith(self.clientID):
                    self.logger.debug("Add message[%s] to resend list" % key)
                    cfg = HalGlobal.gRestartResendMsg[key]
                    seqNum = cfg.msg.SeqNum if cfg.msg.HasField(
                        "SeqNum") else 0
                    self.addToResendList(seq=seqNum, sendagent=self, msg=cfg)

    def disconnectHandler(self, transport):
        """the function will be invoked when the transport layer get a
        disconnect event, the fucntion will clean the agent resources,
        including the socket resource, remove it from the global runtime DB.

        :param transport: the transport object, pull/push
        :return:

        """
        self.logger.info(
            "Got a client[%s] disconnect event, process it in client agent" % self.clientID)

        # we have two transport layer can trigger this handler, we only need one time to process,
        # this flag is used for this
        if self.disconnectProcessed:
            self.logger.info(
                "client disconnect event has been processed")
            return

        # unregister/close the monitor socket
        if self.transportPull.monitor:
            HalGlobal.gMonitorSocketMappingTable.pop(
                self.transportPull.monitor)
            self.poller.unregister(self.transportPull.monitor)
            self.transportPull.socket.disable_monitor()
            self.transportPull.monitor.close()
        if self.transportPush.monitor:
            HalGlobal.gMonitorSocketMappingTable.pop(
                self.transportPush.monitor)
            self.poller.unregister(self.transportPush.monitor)
            self.transportPush.socket.disable_monitor()
            self.transportPush.monitor.close()

        # call the mgr callback to process the disconnect event
        self.mgrDisconnectCb(self)

        # remove the transportPull from the poller
        self.poller.unregister(self.transportPull.socket)

        # remove from the socket agent mapping table
        HalGlobal.gSocketAgentMappingTable.pop(self.transportPull.socket)

        # Remove from the global Agent DB
        self.removeFromAgentDB()

        # close the push and pull, monitor socket
        self.transportPull.close()
        self.transportPush.close()

        self.disconnectProcessed = True

    def sendMsg(self, msg):
        """Send a message via the transport push socket.

        :param msg: a stringlized msg, not the HAlMessage
        :return:

        """
        if msg is None:
            self.logger.error(
                "The msg is None, skip invoking the low level function")
            return

        self.transportPush.send(msg)

    def handleClientHello(self, hello):
        """The Hello message handler.

        :param hello: which is a HalMessage, hold all the info about the hello message
        :return:  NA

        """
        self.logger.debug("Send out the hello rsp message")

        # update the stats
        self.stats.NrMsgs += 1
        self.stats.NrHelloMsgs += 1
        if hello is None:
            msg = "Cannot handle a none client hello message"
            self.logger.error(msg)
            self.stats.NrErrorMsgs += 1
            raise Exception(msg)

        rsp = HalMessage("HalClientHelloRsp",
                         ClientID=hello.msg.ClientID)
        # send out
        self.transportPush.send(rsp.Serialize())
        self.stats.NrHelloRspMsgs += 1

    def handleConfigRsp(self, cfgRsp):
        """This API will handle the configuration response HalMessage from
        client.

        :param cfgRsp:
        :return:

        """
        if cfgRsp is None:
            msg = "Cannot handle a none config response message"
            self.logger.error(msg)
            raise Exception(msg)

        HalGlobal.gHalMsgDbConnection.removeMsgFromDB(
            cfgRsp.msg.SrcClientID + "-" + str(cfgRsp.msg.SeqNum))
        HalGlobal.gDispatcher.dispatchCfgRspMessage(self, cfgRsp)

        self.stats.NrCfgRspMsgs += 1

    def handleNotification(self, notification):
        """This API will handle the notification HalMessage.

        :param notification: the notification HalMessage
        :return:

        """
        if notification is None:
            msg = "Cannot handle the notification since the msg is None"
            self.logger.error(msg)
            raise Exception(msg)
        # update the stats
        self.stats.NrNotifyMsgs += 1
        self.stats.NrMsgs += 1
        HalGlobal.gDispatcher.dispatchNotificationMsg(self, notification)

    def handleConfig(self, cfg):
        """The configuration HalMessage handler.

        :param cfg:  The Config message from the client
        :return:

        """
        if cfg is None:
            msg = "Cannot handle a none config message"
            self.logger.error(msg)
            raise Exception(msg)

        # Add the message to the DB
        seqNum = cfg.msg.SeqNum if cfg.msg.HasField("SeqNum") else 0
        msgBinary = cfg.originalBinary \
            if cfg.originalBinary else cfg.Serialize()
        # add the msg to DB
        HalGlobal.gHalMsgDbConnection.addMsgtoDB(
            msgKey=cfg.msg.SrcClientID + "-" + str(seqNum),
            msg={
                "ClientID": cfg.msg.SrcClientID,
                "Msg": msgBinary
            }
        )

        # Update the stats
        self.stats.NrMsgs += 1
        self.stats.NrCfgMsgs += 1

        # first, process the resendList
        self.processResendList()

        # Dispatch this message to the correct client
        ret = HalGlobal.gDispatcher.dispatchCfgMessage(self, cfg)
        if ret == -1:
            self.addToResendList(seq=seqNum, sendagent=self, msg=cfg)
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
if __name__ == "__main__":

    (ClientID, pullSock, pushSock) = ClientRegisterRandom()

    # generate many clients

    # for i in xrange(1):
    #    ClientRegisterRandom()

    # send out the query issue
    queryMsg = HalMessage("HalClientQuery", ClientID=ClientID)
    binQueryMsg = queryMsg.Serialize()
    hexdump.hexdump(binQueryMsg)

    trans.send(binQueryMsg)
    bin = trans.recv()

    rsp = HalMessage.DeSerialize(bin)

    print rsp.msg

    # send out the driver query
    queryMsg = HalMessage("HalClientQuery", ClientID=ClientID)
    binQueryMsg = queryMsg.Serialize()
    hexdump.hexdump(binQueryMsg)

    trans.send(binQueryMsg)
    bin = trans.recv()

    rsp = HalMessage.DeSerialize(bin)
Ejemplo n.º 11
0
class HalPtpDriver(HalDriverClient):
    """The Driver Client for Hal."""

    SYNC = "ALIGNED"
    LOS = "LOSS OF SYNC"
    __metaclass__ = AddLoggerToClass

    def __init__(self,
                 drvName,
                 drvDesc,
                 drvVer,
                 supportedMsgType,
                 supportedNotificationMsgs,
                 logConfigurePath=None):
        """Init.

        :param drvName: The driver name, such as BCM3160 Driver
        :param drvDesc: A brief description about this driver, such as the 
         driver main functionality description
        :param drvVer: Driver specific version, such as 1.0.1
        :param supportedMsgType: a tuple or list for the driver supported 
         msg types, the form will be (1, 2, 456, 10)
        :param supportedNotificationMsgs: the driver supported notification 
         msg types the form will be (1, 3, 4)
        :return: HalDriverClient object

        """
        super(HalPtpDriver,
              self).__init__(drvName, drvDesc, drvVer, supportedMsgType,
                             supportedNotificationMsgs, logConfigurePath)

        # update the supported messages
        self.HalMsgsHandler = {
            "HalClientRegisterRsp": self.recvRegisterMsgCb,
            "HalClientHelloRsp": self.recvHelloRspMsgCb,
            "HalConfig": self.recvCfgMsgCb,
        }

        self.HalConfigMsgHandlers = {
            MsgTypePtpStatusGet: self.ptp_status_get,
            MsgTypeRdtiConfig: self.config_rdti,
        }

        self.ptpStatus = self.LOS
        self.ptpNewStatus = self.LOS
        self.dispatcher = Dispatcher()

    def start(self, simulate_mode=False):
        """Start polling the transport socket.

        :return:

        """
        self.logger.info("Start the driver client poll...")
        self.connectionSetup()
        self.logger.info("Connection setup done...")

        self.logger.info("Begin register...")
        self.register(self.drvID)
        self.logger.info("End of register...")

        self.dispatcher.loop()

    def ptpdrv_hal_cb(self, sock, mask):
        self.logger.debug("Receive prp drv 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.warning("Got an un-expected error:%s", str(e))
                break

    def register(self, DriverID):
        """Send a register message to Hal and get the client ID from the Hal.

        :return:

        """
        if DriverID is None:
            registerMsg = HalMessage(
                "HalClientRegister",
                ClientName=self.drvname,
                ClientDescription=self.drvDesc,
                ClientVersion=self.drvVer,
                ClientSupportedMessages=self.supportedMsgType,
                ClientSupportedNotificationMessages=self.
                supportedNotificationMsgs)
        else:
            registerMsg = HalMessage(
                "HalClientRegister",
                ClientName=self.drvname,
                ClientDescription=self.drvDesc,
                ClientVersion=self.drvVer,
                ClientSupportedMessages=self.supportedMsgType,
                ClientSupportedNotificationMessages=self.
                supportedNotificationMsgs,
                ClientID=DriverID)

        if self.mgrConnection is None:
            errMsg = "Cannot send the register since the mgr connection is not setup"
            self.logger.error(errMsg)
            raise HalDriverClientError(errMsg)
        self.logger.debug("Send the register msg to Hal...")
        self.mgrConnection.send(registerMsg.Serialize())

    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 register rsp Message from the Hal: %s" %
                          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.ptpdrv_hal_cb)
            self.dispatcher.fd_register(self.pushSock.monitor, zmq.POLLIN,
                                        self.ptpdrv_hal_cb)
            self.dispatcher.fd_register(self.pullSock.monitor, zmq.POLLIN,
                                        self.ptpdrv_hal_cb)
        # send Hello To Hal
        self.sayHelloToHal()
        if self.interestedNotification is not None:
            self.sendInterestedNotifications(self.interestedNotification)

        self.disconnected = False

        return

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

        :return:

        """
        self.logger.info("Create the connection to the mgr....")
        # Create a connection to Hal driver mgr

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

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

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

        # register the mgr socket
        self.dispatcher.fd_register(self.mgrConnection.socket, zmq.POLLIN,
                                    self.ptpdrv_hal_cb)
        self.dispatcher.fd_register(self.mgrConnection.monitor, zmq.POLLIN,
                                    self.ptpdrv_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 connectionDisconnectCb(self, msg):
        """TODO: confusing comment here. Need clarification.

        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.info("A previous event has been processed, skip it!")
            return
        self.logger.info("Detected disconnected, register again")
        # clean up the push and pull socket
        # self.poller.unregister(self.pullSock.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()
        self.register(self.drvID)
        # The zmq lower part will handle the reconnect

        self.disconnected = True

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

        :param hello:
        :return:

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

    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)
        except Exception as e:
            self.logger.error("Got an error:%s, the cfg msg:%s", str(e),
                              cfg.msg)

    def ptp_status_get(self, cfg):
        cfg.msg.CfgMsgPayload = self.SYNC
        self.sendCfgRspMsg(cfg)

    def config_rdti(self, cfg):
        rdti_config_data = t_RcpMessage()
        rdti_config_data.ParseFromString(cfg.msg.CfgMsgPayload)
        rdti_config_data.RcpDataResult = t_RcpMessage.RCP_RESULT_OK
        cfg.msg.CfgMsgPayload = rdti_config_data.SerializeToString()
        self.logger.debug("Recv ptp configuration message, %s" %
                          rdti_config_data)
        self.sendCfgRspMsg(cfg)

    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
        :return:

        """
        cfgMsg = cfg.msg
        rsp = {"Status": HalCommon_pb2.SUCCESS, "ErrorDescription": ""}
        msg = HalMessage("HalConfigRsp",
                         SrcClientID=cfgMsg.SrcClientID,
                         SeqNum=cfgMsg.SeqNum,
                         Rsp=rsp,
                         CfgMsgType=cfgMsg.CfgMsgType,
                         CfgMsgPayload=cfgMsg.CfgMsgPayload)
        self.pushSock.send(msg.Serialize())