1 from __future__
import absolute_import, division
3 from collections
import deque, OrderedDict
7 from twistedActor
import log
10 RO.Comm.Generic.setFramework(
"twisted")
11 from RO.Comm.TCPConnection
import TCPConnection
12 from RO.Comm.Generic
import TCPServer
14 __all__ = [
"MCPMultiplexor"]
25 CharsToStrip =
'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\xfa\xfb\xfc\xfd\xfe\xff'
28 """A server for axis commands
30 Axis commands are prefixed with axis name (and a space) if necessary
32 AxisList = (val[0]
for val
in AxisPortList)
34 """Construct an AxisServer
36 For each command received, the server:
37 - prepends the axis name and a space, if not already present
38 - queues the command by calling queueFunc
40 @param[in] axis axis name
41 @param[in] port port on which to listen to commands for this axis
42 @param[in] queueFunc function to call when a command is to be queued;
43 must take three arguments: cmdStr, socket, prefixStr
46 raise RuntimeError(
"axis=%r; must be one of %s" % (axis, self.
AxisList))
55 def _readCallback(self, sock):
56 """Called when a command is received
58 cmdStr = sock.readLine()
68 def _stateCallback(self, conn):
69 log.info(
"%s conn state=%s" % (self.
axisPrefix, conn.state,))
76 """Multiplex axis controller ports into one MCP port
78 Axis commands are prefixed with axis name (and a space) if necessary
80 Facility = syslog.LOG_LOCAL4
81 AxisPortDict = OrderedDict(AxisPortList)
83 """!Construct an MCPMultiplexor
85 @param[in] mcpHost MCP host
86 @param[in] mcpPort MCP port
94 log.info(
"starting MCP connection to %s, %s" % (mcpHost, mcpPort))
103 self._mcpConn.connect()
106 """Show the current state of the queue
110 log.info(
"queue=[%s] <--next to execute"%(
", ".join([cmdTuple[-1] +
" " + cmdTuple[0]
for cmdTuple
in self.
_cmdQueue])))
113 def _mcpConnStateCallback(self, conn):
114 log.info(
"MCP conn state=%s" % (conn.state,))
116 log.info(
"MCP connection made; starting up axis servers")
119 for axis, axisPort
in self.AxisPortDict.iteritems())
120 elif conn.isDisconnected:
121 log.info(
"MCP connection done; killing axis servers")
124 for server
in self._axisServerDict.itervalues():
129 """Add a command to the command queue
131 @param[in] cmdStr command to queue
132 @param[in] sock socket to which to write replies
133 @param[in] prefixStr prefix prepended to cmdStr
135 log.info(
"queue %r for %s" % (cmdStr, sock))
136 self._cmdQueue.appendleft((cmdStr, sock, prefixStr))
140 def _mcpReadCallback(self, sock, replyStr):
141 """Called when data is read from the MCP
148 replyStr = replyStr.translate(string.maketrans(
"",
""), CharsToStrip)
152 if replyStr
and prefixStr
and replyStr.startswith(prefixStr):
153 replyStr = replyStr[len(prefixStr):]
160 sock.writeLine(replyStr)
162 log.warn(
"Could not write to %s: %s" % (sock, e))
163 if replyStr ==
"OK" or replyStr.endswith(
" OK"):
168 log.warn(
"read %r from MCP, unsolicited" % (replyStr,))
171 """Start a new command, if ready to do so, else do nothing
175 cmdStr, sock, prefixStr = self._cmdQueue.pop()
177 log.info(
"sending %r to MCP" % (cmdStr,))
179 self._mcpConn.writeLine(cmdStr)
def __init__
Construct an MCPMultiplexor.
def _mcpConnStateCallback