Esempio n. 1
0
    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
Esempio n. 2
0
    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)
Esempio n. 3
0
    def connection_setup(self):
        """Create the connection to the mgr and setup the poller.

        :return:

        """

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

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

        # register the mgr socket
        self.dispatcher.fd_register(self.mgrConnection.socket,
                                    self.dispatcher.EV_FD_IN,
                                    self.fault_management_cb)
        self.dispatcher.fd_register(self.mgrConnection.monitor,
                                    self.dispatcher.EV_FD_IN,
                                    self.fault_management_cb)
Esempio n. 4
0
    def test_poller(self):
        """test create HalPoller.

        check whether the socket can be register, if
        the socket can't find in poller map case fail

        check whether the socket
        can be unregister, if the socket can find in poller map case fail.

        :keyword:HalPoller
        :exception:assertIn(pullSock.socket, poller.poller._map),
                   assertNotIn(pullSock.socket, poller.poller._map)
        :parameter:
        :return:

        """
        pullSock = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalServerMode,
            index=20, socketMode=HalTransport.HalSocketPullMode,
            disconnectHandlerCb=None)

        poller = HalPoller()

        poller.register(pullSock.socket)
        self.assertIn(pullSock.socket, poller.poller._map)
        poller.unregister(pullSock.socket)
        self.assertNotIn(pullSock.socket, poller.poller._map)
        poller.register(pullSock.socket)

        socks = poller.poll(500)

        pullSock.socket.disable_monitor()
        pullSock.monitor.close()
        pullSock.close()
Esempio n. 5
0
    def recvRegisterMsgCb(self, cfg):  # pragma: no cover
        """The callback handler for the configuration message.

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

        """

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

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

        self.drvID = cfg.msg.ClientID

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

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

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

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

        self.disconnected = False

        return
Esempio n. 6
0
 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)
Esempio n. 7
0
 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)
Esempio n. 8
0
    def test_register(self):
        """test HalTransport#register.

        check whether none socket can be
        register, if the specific exception can't be catch case fail

        check
        whether the socket can be register, if the socket can't find in poller
        map case fail.

        :keyword:HalTransport#register
        :exception:assertEqual(str(e), "Cannot register to a None poller"),
                   assertIn(pullSock.socket, poller.poller._map)
        :parameter:
        :return:

        """
        pullSock = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalServerMode,
            index=20, socketMode=HalTransport.HalSocketPullMode,
            disconnectHandlerCb=None)

        poller = HalPoller()
        try:
            pullSock.register(None)
        except Exception as e:
            self.assertEqual(str(e), "Cannot register to a None poller")

        pullSock.register(poller)

        self.assertIn(pullSock.socket, poller.poller._map)

        pullSock.socket.disable_monitor()
        pullSock.monitor.close()
        pullSock.close()
Esempio n. 9
0
 def test_creative(self):
     try:
         transport = HalTransport(1000, HalTransport.HalClientMode,
                                  index=0, socketMode=HalTransport.HalSocketPullMode,
                                  disconnectHandlerCb=None)
     except Exception as e:
         self.assertEqual(str(e), "Unsupported HalTransportType")
Esempio n. 10
0
    def test_getMonitorEndpoint(self):

        msg = {
            "endpoint": 0x12345,
        }

        self.assertEqual(HalTransport.getMonitorEndpoint(msg), 0x12345)
Esempio n. 11
0
    def __init__(self, MgrType, poller):
        """
        :param MgrType: The manager type
        :param poller: a global poller, which we can register the manager to it
        :return: Manager object

        """

        if MgrType == HalTransport.HalTransportClientMgr:
            self.logger.info("Create the Hal client manager...")
        else:
            self.logger.error("Unexcepted MgrType got: %s" % str(MgrType))

        # create the Clinet manager
        self.transport = HalTransport(
            MgrType,
            HalTransport.HalServerMode,
            disconnectHandlerCb=self.disconnectHandler)

        self.poller = poller

        # register to the poller
        self.poller.register(self.transport.socket)

        # Add this socket to the socket agent mapping table
        HalGlobal.gSocketAgentMappingTable[self.transport.socket] = self

        # process the monitor socket
        if not (self.transport.monitor is None):
            HalGlobal.gMonitorSocketMappingTable[
                self.transport.monitor] = self.transport
            self.poller.register(self.transport.monitor)
Esempio n. 12
0
    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)
Esempio n. 13
0
    def connectionSetup(self, dispatcher):
        """Create the connection to the mgr and setup the poller.

        :return:

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

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

        # register the mgr socket
        dispatcher.fd_register(self.mgrConnection.socket, zmq.POLLIN,
                               self.provmgr_cb)
        dispatcher.fd_register(self.mgrConnection.monitor, zmq.POLLIN,
                               self.provmgr_cb)
Esempio n. 14
0
    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)
Esempio n. 15
0
    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
Esempio n. 16
0
    def setUpClass(cls):
        global_dispatcher = Dispatcher()
        cls.hal_client =\
            HalPtpClient("PTPClient", "This is a PTP application", "1.9.0",
                         [MsgTypeRoutePtpStatus, MsgTypeGeneralNtf, ],
                         [MsgTypePtpClockStatus, MsgTypeRpdState, ],
                         global_dispatcher, None)

        cls.hal_client.pushSock = HalTransport(
            HalTransport.HalTransportClientAgentPull,
            HalTransport.HalClientMode,
            index=19,
            socketMode=HalTransport.HalSocketPushMode,
            disconnectHandlerCb=None)
Esempio n. 17
0
 def setUpClass(cls):
     setup_logging("GCPP Unit test")
     setup_test_redis()
     cls.fwdCfg = StaticL2tpProvision()
     cls.ApiPath = \
         L2tpv3GlobalSettings.L2tpv3GlobalSettings.APITransportPath
     cls.api = L2tpv3API(cls.ApiPath)
     global_dispatcher = Dispatcher()
     cls.hal_client = L2tpHalClient("L2TP_HAL_CLIENT",
                                    "the HAL client of L2TP feature", "1.0",
                                    tuple(
                                        L2tpHalClient.notification_list.keys()),
                                    global_dispatcher)
     cls.hal_client.pushSock = HalTransport(
         HalTransport.HalTransportClientAgentPull,
         HalTransport.HalClientMode, index=19,
         socketMode=HalTransport.HalSocketPushMode,
         disconnectHandlerCb=None)
Esempio n. 18
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
Esempio n. 19
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")
Esempio n. 20
0
    def test_createTransport(self):

        transportMgr = HalTransport(
            HalTransport.HalTransportClientMgr, HalTransport.HalServerMode,
            disconnectHandlerCb=None)
        transportMgr.socket.disable_monitor()
        transportMgr.monitor.close()
        transportMgr.close()
        self.assertIsNotNone(transportMgr)
        try:
            shutil.rmtree(os.path.dirname("/tmp/HalUnitTest/"))
        except Exception as e:
            pass
        transportClient = HalTransport(
            HalTransport.HalTransportClientMgr, HalTransport.HalClientMode)
        transportClient.socket.disable_monitor()
        transportClient.monitor.close()
        transportClient.close()
        self.assertIsNotNone(transportClient)

        transportAgentPush = HalTransport(
            HalTransport.HalTransportClientAgentPush, HalTransport.HalServerMode,
            index=0, socketMode=HalTransport.HalSocketPushMode,
            disconnectHandlerCb=None)
        transportAgentPush.socket.disable_monitor()
        transportAgentPush.monitor.close()
        transportAgentPush.close()
        self.assertIsNotNone(transportAgentPush)

        transportAgentPull = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalServerMode,
            index=0, socketMode=HalTransport.HalSocketPullMode,
            disconnectHandlerCb=None)
        transportAgentPull.socket.disable_monitor()
        transportAgentPull.monitor.close()
        transportAgentPull.close()
        self.assertIsNotNone(transportAgentPull)

        transportAgentPull = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalClientMode,
            index=0, socketMode=HalTransport.HalSocketPullMode,
            disconnectHandlerCb=None)
        transportAgentPull.socket.disable_monitor()
        transportAgentPull.monitor.close()
        transportAgentPull.close()
        self.assertIsNotNone(transportAgentPull)

        # error case
        try:
            transport = HalTransport(1000, HalTransport.HalClientMode,
                                     index=0, socketMode=HalTransport.HalSocketPullMode,
                                     disconnectHandlerCb=None)
        except Exception as e:
            self.assertEqual(str(e), "Unsupported HalTransportType")
Esempio n. 21
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
Esempio n. 22
0
class FaultManagementClient(HalDriverClient):
    """
    refactor the class for fault management
    """
    __metaclass__ = AddLoggerToClass

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            evts.pop(entry)

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

        return evtNtfList

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

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

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

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

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

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

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

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

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

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

        :return:

        """

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

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

        :return:

        """

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

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

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

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

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

        """

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

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

        self.drvID = cfg.msg.ClientID

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

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

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

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

        self.disconnected = False

        return

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

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

        """

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

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

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

        :param cfg:
        :return:

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

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

        self.logger.debug("Recv a notification message\n%s", str(msg.msg))
        self.process_notification_msg(msg)
Esempio n. 23
0
    def test_recv(self):
        """test HalTransport#recv.

        check if it can handle the method event, with
        the exception/logicality's correct

        check whether hello message can be
        receive after send out, if the returned value match case fail.

        :keyword:HalTransport#recv
        :exception:assertEqual(pullSock.recv(), "hello")
        :parameter:
        :return:

        """
        pullSock = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalServerMode,
            index=20, socketMode=HalTransport.HalSocketPullMode,
            disconnectHandlerCb=None)
        pullSock.socket.disable_monitor()
        pullSock.monitor.close()
        pullSock.close()

        pullSock = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalServerMode,
            index=20, socketMode=HalTransport.HalSocketPullMode,
            disconnectHandlerCb=None)
        pushSock = HalTransport(
            HalTransport.HalTransportClientAgentPull, HalTransport.HalClientMode,
            index=20, socketMode=HalTransport.HalSocketPushMode, disconnectHandlerCb=None)

        pushSock.send("hello")
        print("Try to receive the message")
        self.assertEqual("hello", pullSock.recv())

        pullSock.socket.disable_monitor()
        pullSock.monitor.close()
        pullSock.close()

        pushSock.socket.disable_monitor()
        pushSock.monitor.close()
        pushSock.close()
Esempio n. 24
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
Esempio n. 25
0
class ProvMgrHalDriver(HalDriverClient):
    __metaclass__ = AddLoggerToClass

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

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

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

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

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

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

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

    RESET_CTRL_FILENAME = '/rpd/config/reset_ctrl'

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

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

        self.drvID = cfg.msg.ClientID

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

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

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

        self.disconnected = False

        return

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

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

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

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

        :param cfgMsg:
        :return:

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

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

        self.sendCfgRspMsg(cfgMsg, rsp)

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

        :param cfg:
        :return:

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

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

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

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

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

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

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

        :param ntf:
        :return:

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

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

        :param hello:
        :return:

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

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

        :return:

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

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

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

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

        :param msg:
        :return:

        """

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

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

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

        self.disconnected = True

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

        :return:

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

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

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

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

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

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

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

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

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

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

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

        return True

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

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

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

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

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

    def sendOperationalStatusNtf(self, operational):
        """
        :param operational:  True or False to represent the current operational status
        :return:
        """
        led_msg = t_LED()
        led_msg.setLed.ledType = led_msg.LED_TYPE_STATUS
        led_msg.setLed.color = led_msg.LED_COLOR_GREEN
        if operational:
            led_msg.setLed.action = led_msg.LED_ACTION_LIT
        else:
            led_msg.setLed.action = led_msg.LED_ACTION_DARK
        self.logger.debug("Set led notification message: %s", led_msg)
        self.sendNotificationMsg(MsgTypeSetLed, led_msg.SerializeToString())
Esempio n. 26
0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import zmq
import hexdump
from rpd.hal.src.transport.HalTransport import HalTransport
from rpd.hal.src.msg.HalMessage import HalMessage
from rpd.hal.src.msg import HalCommon_pb2
from rpd.hal.src.msg.HalOperation_pb2 import HalNotification
from rpd.hal.src.msg.ClientProvision_pb2 import HalClientRegister

if __name__ == "__main__":
    trans = HalTransport(HalTransport.HalTransportClientMgr,
                         HalTransport.HalClientMode)
    trans.connects()

    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
Esempio n. 27
0
    def test_eventHandlerMonitor(self):
        """test HalTransport#monitorHandler,

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

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

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

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

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

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

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

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

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

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

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

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

        transport.socket.disable_monitor()
        transport.monitor.close()
        transport.close()
Esempio n. 28
0
    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)
Esempio n. 29
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()
Esempio n. 30
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()