示例#1
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()
示例#2
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
示例#3
0
    registerMsg = HalClientRegister()
    registerMsg.MsgType = "HalClientRegister"
    registerMsg.ClientName = "Test"
    registerMsg.ClientDescription = "This is a test msg"
    registerMsg.ClientVersion = "1.0"
    registerMsg.ClientSupportedMessages.append(1)
    registerMsg.ClientSupportedMessages.append(123)
    registerMsg.ClientSupportedNotificationMessages.append(11)
    registerMsg.ClientSupportedNotificationMessages.append(12)

    strMsg = registerMsg.SerializeToString()

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

    rsp = HalMessage.DeSerialize(bin)

    ClientID = rsp.msg.ClientID

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

    print ClientID
    print pull
    print push

    # Create the Pull interface
    context = HalTransport.context