Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Leherbauer2012-01-23 04:28:01 -0500
committerAnton Leherbauer2012-01-23 04:28:01 -0500
commit6f047bf6a21dcc9be9bf444da123e8b32834da52 (patch)
tree22cc2972f8bfa7a3693aa514ecef25581dd2dd32
parenta1b540e1272eda3d1b09f3232512db9cc0f1d168 (diff)
downloadorg.eclipse.tcf-6f047bf6a21dcc9be9bf444da123e8b32834da52.tar.gz
org.eclipse.tcf-6f047bf6a21dcc9be9bf444da123e8b32834da52.tar.xz
org.eclipse.tcf-6f047bf6a21dcc9be9bf444da123e8b32834da52.zip
TCF Python: Unify line endings.
-rw-r--r--python/.project34
-rw-r--r--python/src/tcf/EventQueue.py162
-rw-r--r--python/src/tcf/__init__.py126
-rw-r--r--python/src/tcf/channel/ChannelProxy.py194
-rw-r--r--python/src/tcf/channel/StreamChannel.py260
-rw-r--r--python/src/tcf/channel/__init__.py378
-rw-r--r--python/src/tcf/errors.py322
-rw-r--r--python/src/tcf/peer.py548
-rw-r--r--python/src/tcf/services/__init__.py254
-rw-r--r--python/src/tcf/services/breakpoints.py626
-rw-r--r--python/src/tcf/services/diagnostics.py570
-rw-r--r--python/src/tcf/services/disassembly.py262
-rw-r--r--python/src/tcf/services/expressions.py712
-rw-r--r--python/src/tcf/services/filesystem.py1206
-rw-r--r--python/src/tcf/services/linenumbers.py264
-rw-r--r--python/src/tcf/services/local/LocatorService.py1614
-rw-r--r--python/src/tcf/services/local/__init__.py20
-rw-r--r--python/src/tcf/services/locator.py188
-rw-r--r--python/src/tcf/services/memory.py606
-rw-r--r--python/src/tcf/services/memorymap.py376
-rw-r--r--python/src/tcf/services/pathmap.py306
-rw-r--r--python/src/tcf/services/processes.py680
-rw-r--r--python/src/tcf/services/processes_v1.py94
-rw-r--r--python/src/tcf/services/registers.py936
-rw-r--r--python/src/tcf/services/remote/BreakpointsProxy.py298
-rw-r--r--python/src/tcf/services/remote/DiagnosticsProxy.py348
-rw-r--r--python/src/tcf/services/remote/DisassemblyProxy.py116
-rw-r--r--python/src/tcf/services/remote/ExpressionsProxy.py268
-rw-r--r--python/src/tcf/services/remote/FileSystemProxy.py1018
-rw-r--r--python/src/tcf/services/remote/LineNumbersProxy.py134
-rw-r--r--python/src/tcf/services/remote/LocatorProxy.py298
-rw-r--r--python/src/tcf/services/remote/MemoryMapProxy.py164
-rw-r--r--python/src/tcf/services/remote/MemoryProxy.py484
-rw-r--r--python/src/tcf/services/remote/PathMapProxy.py112
-rw-r--r--python/src/tcf/services/remote/ProcessesProxy.py430
-rw-r--r--python/src/tcf/services/remote/ProcessesV1Proxy.py64
-rw-r--r--python/src/tcf/services/remote/RegistersProxy.py352
-rw-r--r--python/src/tcf/services/remote/RunControlProxy.py316
-rw-r--r--python/src/tcf/services/remote/StackTraceProxy.py108
-rw-r--r--python/src/tcf/services/remote/StreamsProxy.py292
-rw-r--r--python/src/tcf/services/remote/SymbolsProxy.py242
-rw-r--r--python/src/tcf/services/remote/SysMonitorProxy.py154
-rw-r--r--python/src/tcf/services/remote/TerminalsProxy.py246
-rw-r--r--python/src/tcf/services/runcontrol.py964
-rw-r--r--python/src/tcf/services/stacktrace.py324
-rw-r--r--python/src/tcf/services/streams.py448
-rw-r--r--python/src/tcf/services/symbols.py783
-rw-r--r--python/src/tcf/services/sysmonitor.py804
-rw-r--r--python/src/tcf/services/terminals.py444
-rw-r--r--python/src/tcf/shell.py202
-rw-r--r--python/src/tcf/tests/BasicTests.py1320
-rw-r--r--python/src/tcf/transport.py316
-rw-r--r--python/src/tcf/util/__init__.py20
-rw-r--r--python/src/tcf/util/cache.py540
-rw-r--r--python/src/tcf/util/event.py172
-rw-r--r--python/src/tcf/util/logging.py108
-rw-r--r--python/src/tcf/util/sync.py444
-rw-r--r--python/src/tcf/util/task.py360
58 files changed, 11716 insertions, 11715 deletions
diff --git a/python/.project b/python/.project
index ea91adff9..e46b0ca9a 100644
--- a/python/.project
+++ b/python/.project
@@ -1,17 +1,17 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.eclipse.tcf.python</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.python.pydev.PyDevBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.python.pydev.pythonNature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tcf.python</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.python.pydev.PyDevBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.python.pydev.pythonNature</nature>
+ </natures>
+</projectDescription>
diff --git a/python/src/tcf/EventQueue.py b/python/src/tcf/EventQueue.py
index 0efc5f60c..cc38aa245 100644
--- a/python/src/tcf/EventQueue.py
+++ b/python/src/tcf/EventQueue.py
@@ -1,81 +1,81 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-import threading
-import protocol
-
-class EventQueue(object):
-
- def __init__(self, on_shutdown=None):
- self.__thread = threading.Thread(target=self, name="TCF Event Dispatcher")
- self.__thread.daemon = True
- self.__is_waiting = False
- self.__is_shutdown = False
- self.__on_shutdown = on_shutdown
- self.__lock = threading.Condition()
- self.__queue = []
-
- def start(self):
- self.__thread.start()
-
- def shutdown(self):
- try:
- if self.__on_shutdown:
- self.__on_shutdown()
- with self.__lock:
- self.__is_shutdown = True
- if self.__is_waiting:
- self.__is_waiting = False
- self.__lock.notifyAll()
- self.__thread.join()
- except Exception as e:
- protocol.log("Failed to shutdown TCF event dispatch thread", e)
-
- def isShutdown(self):
- with self._lock:
- return self.__is_shutdown
-
- def __error(self, x):
- protocol.log("Unhandled exception in TCF event dispatch", x)
-
- def __call__(self):
- while True:
- try:
- with self.__lock:
- while not self.__queue:
- if self.__is_shutdown: return
- self.__is_waiting = True
- self.__lock.wait()
- r, args, kwargs = self.__queue.pop(0)
- r(*args, **kwargs)
- except Exception as x:
- self.__error(x)
-
- def invokeLater(self, r, *args, **kwargs):
- assert r
- with self.__lock:
- if self.__is_shutdown: raise RuntimeError("TCF event dispatcher has shut down")
- self.__queue.append((r, args, kwargs))
- if self.__is_waiting:
- self.__is_waiting = False
- self.__lock.notifyAll()
-
- def isDispatchThread(self):
- return threading.currentThread() is self.__thread
-
- def getCongestion(self):
- with self.__lock:
- job_cnt = 0
- l0 = job_cnt / 10 - 100
- l1 = len(self.__queue) / 10 - 100
- if l1 > l0: l0 = l1
- if l0 > 100: l0 = 100
- return l0
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+import threading
+import protocol
+
+class EventQueue(object):
+
+ def __init__(self, on_shutdown=None):
+ self.__thread = threading.Thread(target=self, name="TCF Event Dispatcher")
+ self.__thread.daemon = True
+ self.__is_waiting = False
+ self.__is_shutdown = False
+ self.__on_shutdown = on_shutdown
+ self.__lock = threading.Condition()
+ self.__queue = []
+
+ def start(self):
+ self.__thread.start()
+
+ def shutdown(self):
+ try:
+ if self.__on_shutdown:
+ self.__on_shutdown()
+ with self.__lock:
+ self.__is_shutdown = True
+ if self.__is_waiting:
+ self.__is_waiting = False
+ self.__lock.notifyAll()
+ self.__thread.join()
+ except Exception as e:
+ protocol.log("Failed to shutdown TCF event dispatch thread", e)
+
+ def isShutdown(self):
+ with self._lock:
+ return self.__is_shutdown
+
+ def __error(self, x):
+ protocol.log("Unhandled exception in TCF event dispatch", x)
+
+ def __call__(self):
+ while True:
+ try:
+ with self.__lock:
+ while not self.__queue:
+ if self.__is_shutdown: return
+ self.__is_waiting = True
+ self.__lock.wait()
+ r, args, kwargs = self.__queue.pop(0)
+ r(*args, **kwargs)
+ except Exception as x:
+ self.__error(x)
+
+ def invokeLater(self, r, *args, **kwargs):
+ assert r
+ with self.__lock:
+ if self.__is_shutdown: raise RuntimeError("TCF event dispatcher has shut down")
+ self.__queue.append((r, args, kwargs))
+ if self.__is_waiting:
+ self.__is_waiting = False
+ self.__lock.notifyAll()
+
+ def isDispatchThread(self):
+ return threading.currentThread() is self.__thread
+
+ def getCongestion(self):
+ with self.__lock:
+ job_cnt = 0
+ l0 = job_cnt / 10 - 100
+ l1 = len(self.__queue) / 10 - 100
+ if l1 > l0: l0 = l1
+ if l0 > 100: l0 = 100
+ return l0
diff --git a/python/src/tcf/__init__.py b/python/src/tcf/__init__.py
index 5918652db..9978c6234 100644
--- a/python/src/tcf/__init__.py
+++ b/python/src/tcf/__init__.py
@@ -1,63 +1,63 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-TCF - Target Communication Framework
-"""
-
-import types
-import protocol, peer, channel
-from util import task
-
-__all__ = ('connect')
-
-def connect(params, wait=True):
- """Connect to peer. Argument is a string of the form <transport>:<host>:<port>,
- e.g. "TCP:127.0.0.1:1534" """
- if type(params) is types.StringType:
- params = _parse_params(params)
- elif type(params) is not types.DictType:
- raise TypeError("Expected string or dict")
- p = peer.TransientPeer(params)
- if wait:
- c = task.Task(_openChannel, p).get()
- else:
- c = protocol.invokeAndWait(p.openChannel)
- return c
-
-def peers():
- "Return list of discovered remote peers"
- locator = protocol.getLocator()
- if locator:
- return protocol.invokeAndWait(locator.getPeers)
-
-def _openChannel(p, done=None):
- assert protocol.isDispatchThread()
- c = p.openChannel()
- if done is None: return
- class ChannelListener(channel.ChannelListener):
- def onChannelOpened(self):
- c.removeChannelListener(self)
- done(None, c)
- def onChannelClosed(self, error):
- done(error, None)
- c.addChannelListener(ChannelListener())
-
-def _parse_params(paramStr):
- args = paramStr.split(":")
- if len(args) != 3:
- raise ValueError("Expected format: <transport>:<host>:<port>")
- transp, host, port = args
- return {
- peer.ATTR_IP_HOST : host,
- peer.ATTR_IP_PORT : port,
- peer.ATTR_TRANSPORT_NAME : transp
- }
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+TCF - Target Communication Framework
+"""
+
+import types
+import protocol, peer, channel
+from util import task
+
+__all__ = ('connect')
+
+def connect(params, wait=True):
+ """Connect to peer. Argument is a string of the form <transport>:<host>:<port>,
+ e.g. "TCP:127.0.0.1:1534" """
+ if type(params) is types.StringType:
+ params = _parse_params(params)
+ elif type(params) is not types.DictType:
+ raise TypeError("Expected string or dict")
+ p = peer.TransientPeer(params)
+ if wait:
+ c = task.Task(_openChannel, p).get()
+ else:
+ c = protocol.invokeAndWait(p.openChannel)
+ return c
+
+def peers():
+ "Return list of discovered remote peers"
+ locator = protocol.getLocator()
+ if locator:
+ return protocol.invokeAndWait(locator.getPeers)
+
+def _openChannel(p, done=None):
+ assert protocol.isDispatchThread()
+ c = p.openChannel()
+ if done is None: return
+ class ChannelListener(channel.ChannelListener):
+ def onChannelOpened(self):
+ c.removeChannelListener(self)
+ done(None, c)
+ def onChannelClosed(self, error):
+ done(error, None)
+ c.addChannelListener(ChannelListener())
+
+def _parse_params(paramStr):
+ args = paramStr.split(":")
+ if len(args) != 3:
+ raise ValueError("Expected format: <transport>:<host>:<port>")
+ transp, host, port = args
+ return {
+ peer.ATTR_IP_HOST : host,
+ peer.ATTR_IP_PORT : port,
+ peer.ATTR_TRANSPORT_NAME : transp
+ }
diff --git a/python/src/tcf/channel/ChannelProxy.py b/python/src/tcf/channel/ChannelProxy.py
index eca426e3c..dc0802759 100644
--- a/python/src/tcf/channel/ChannelProxy.py
+++ b/python/src/tcf/channel/ChannelProxy.py
@@ -1,97 +1,97 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-ChannelProxy implements forwarding of TCF messages between two channels.
-The class is used to implement Locator service "redirect" command.
-"""
-
-from tcf import channel
-
-class ProxyCommandListener(channel.CommandListener):
- def __init__(self, ch, tokens):
- self.ch = ch
- self.tokens = tokens
- def progress(self, token, data):
- self.ch.sendProgress(self.tokens.get(token), data)
- def result(self, token, data):
- self.ch.sendResult(self.tokens.pop(token, None), data)
- def terminated(self, token, error):
- self.ch.rejectCommand(self.tokens.pop(token, None))
-
-class ChannelProxy(object):
- def __init__(self, x, y):
- #assert not isinstance(x, ChannelLoop)
- #assert not isinstance(y, ChannelLoop)
- self.ch_x = x
- self.ch_y = y
- assert self.ch_x.getState() == channel.STATE_OPEN
- assert self.ch_y.getState() == channel.STATE_OPENING
- self.tokens_x = {}
- self.tokens_y = {}
- cmd_listener_x = ProxyCommandListener(self.ch_x, self.tokens_x)
- cmd_listener_y = ProxyCommandListener(self.ch_y, self.tokens_y)
- proxy = self
-
- class ProxyX(channel.Proxy):
- def onChannelClosed(self, error):
- proxy.closed_x = True
- if proxy.closed_y: return
- if error is None: proxy.ch_y.close()
- else: proxy.ch_y.terminate(error)
- def onCommand(self, token, service, name, data):
- if proxy.closed_y: return
- assert proxy.ch_y.getState() == channel.STATE_OPEN
- s = proxy.ch_y.getRemoteService(service)
- if not s: proxy.ch_x.terminate(IOError("Invalid service name"))
- else: proxy.tokens_x[proxy.ch_y.sendCommand(s, name, data, cmd_listener_x)] = token
- def onEvent(self, service, name, data):
- s = proxy.ch_x.getRemoteService(service)
- if not s: proxy.ch_x.terminate(IOError("Invalid service name"))
- elif not proxy.closed_y: proxy.ch_y.sendEvent(s, name, data)
-
- class ProxyY(channel.Proxy):
- def onChannelClosed(self, error):
- proxy.closed_y = True
- if proxy.closed_x: return
- if error is None: proxy.ch_x.close()
- else: proxy.ch_x.terminate(error)
- def onCommand(self, token, service, name, data):
- if proxy.closed_x: return
- assert proxy.ch_x.getState() == channel.STATE_OPEN
- s = proxy.ch_x.getRemoteService(service)
- if not s: proxy.ch_y.terminate(IOError("Invalid service name"))
- else: proxy.tokens_y[proxy.ch_x.sendCommand(s, name, data, cmd_listener_y)] = token
- def onEvent(self, service, name, data):
- s = proxy.ch_y.getRemoteService(service)
- if not s: proxy.ch_y.terminate(IOError("Invalid service name"))
- elif not proxy.closed_x: proxy.ch_x.sendEvent(s, name, data)
-
- proxy_x = ProxyX()
- proxy_y = ProxyY()
-
- try:
- self.ch_y.setProxy(proxy_y, self.ch_x.getRemoteServices())
- class ChannelListener(channel.ChannelListener):
- def onChannelClosed(self, error):
- proxy.ch_y.removeChannelListener(self)
- if error is None: error = Exception("Channel closed")
- def onChannelOpened(self):
- proxy.ch_y.removeChannelListener(self)
- try:
- proxy.ch_x.setProxy(proxy_x, proxy.ch_y.getRemoteServices())
- except IOError as e:
- proxy.ch_x.terminate(e)
- proxy.ch_y.terminate(e)
- self.ch_y.addChannelListener(ChannelListener())
- except IOError as e:
- self.ch_x.terminate(e)
- self.ch_y.terminate(e)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+ChannelProxy implements forwarding of TCF messages between two channels.
+The class is used to implement Locator service "redirect" command.
+"""
+
+from tcf import channel
+
+class ProxyCommandListener(channel.CommandListener):
+ def __init__(self, ch, tokens):
+ self.ch = ch
+ self.tokens = tokens
+ def progress(self, token, data):
+ self.ch.sendProgress(self.tokens.get(token), data)
+ def result(self, token, data):
+ self.ch.sendResult(self.tokens.pop(token, None), data)
+ def terminated(self, token, error):
+ self.ch.rejectCommand(self.tokens.pop(token, None))
+
+class ChannelProxy(object):
+ def __init__(self, x, y):
+ #assert not isinstance(x, ChannelLoop)
+ #assert not isinstance(y, ChannelLoop)
+ self.ch_x = x
+ self.ch_y = y
+ assert self.ch_x.getState() == channel.STATE_OPEN
+ assert self.ch_y.getState() == channel.STATE_OPENING
+ self.tokens_x = {}
+ self.tokens_y = {}
+ cmd_listener_x = ProxyCommandListener(self.ch_x, self.tokens_x)
+ cmd_listener_y = ProxyCommandListener(self.ch_y, self.tokens_y)
+ proxy = self
+
+ class ProxyX(channel.Proxy):
+ def onChannelClosed(self, error):
+ proxy.closed_x = True
+ if proxy.closed_y: return
+ if error is None: proxy.ch_y.close()
+ else: proxy.ch_y.terminate(error)
+ def onCommand(self, token, service, name, data):
+ if proxy.closed_y: return
+ assert proxy.ch_y.getState() == channel.STATE_OPEN
+ s = proxy.ch_y.getRemoteService(service)
+ if not s: proxy.ch_x.terminate(IOError("Invalid service name"))
+ else: proxy.tokens_x[proxy.ch_y.sendCommand(s, name, data, cmd_listener_x)] = token
+ def onEvent(self, service, name, data):
+ s = proxy.ch_x.getRemoteService(service)
+ if not s: proxy.ch_x.terminate(IOError("Invalid service name"))
+ elif not proxy.closed_y: proxy.ch_y.sendEvent(s, name, data)
+
+ class ProxyY(channel.Proxy):
+ def onChannelClosed(self, error):
+ proxy.closed_y = True
+ if proxy.closed_x: return
+ if error is None: proxy.ch_x.close()
+ else: proxy.ch_x.terminate(error)
+ def onCommand(self, token, service, name, data):
+ if proxy.closed_x: return
+ assert proxy.ch_x.getState() == channel.STATE_OPEN
+ s = proxy.ch_x.getRemoteService(service)
+ if not s: proxy.ch_y.terminate(IOError("Invalid service name"))
+ else: proxy.tokens_y[proxy.ch_x.sendCommand(s, name, data, cmd_listener_y)] = token
+ def onEvent(self, service, name, data):
+ s = proxy.ch_y.getRemoteService(service)
+ if not s: proxy.ch_y.terminate(IOError("Invalid service name"))
+ elif not proxy.closed_x: proxy.ch_x.sendEvent(s, name, data)
+
+ proxy_x = ProxyX()
+ proxy_y = ProxyY()
+
+ try:
+ self.ch_y.setProxy(proxy_y, self.ch_x.getRemoteServices())
+ class ChannelListener(channel.ChannelListener):
+ def onChannelClosed(self, error):
+ proxy.ch_y.removeChannelListener(self)
+ if error is None: error = Exception("Channel closed")
+ def onChannelOpened(self):
+ proxy.ch_y.removeChannelListener(self)
+ try:
+ proxy.ch_x.setProxy(proxy_x, proxy.ch_y.getRemoteServices())
+ except IOError as e:
+ proxy.ch_x.terminate(e)
+ proxy.ch_y.terminate(e)
+ self.ch_y.addChannelListener(ChannelListener())
+ except IOError as e:
+ self.ch_x.terminate(e)
+ self.ch_y.terminate(e)
diff --git a/python/src/tcf/channel/StreamChannel.py b/python/src/tcf/channel/StreamChannel.py
index a572f83ac..9c6d2239a 100644
--- a/python/src/tcf/channel/StreamChannel.py
+++ b/python/src/tcf/channel/StreamChannel.py
@@ -1,130 +1,130 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-import types
-from AbstractChannel import AbstractChannel, EOS, EOM
-
-ESC = 3
-
-class StreamChannel(AbstractChannel):
- """
- Abstract channel implementation for stream oriented transport protocols.
-
- StreamChannel implements communication link connecting two end points (peers).
- The channel asynchronously transmits messages: commands, results and events.
-
- StreamChannel uses escape sequences to represent End-Of-Message and End-Of-Stream markers.
-
- Clients can subclass StreamChannel to support particular stream oriented transport (wire) protocol.
- Also, see ChannelTCP for a concrete IChannel implementation that works on top of TCP sockets as a transport.
- """
-
- def __init__(self, remote_peer, local_peer=None):
- super(StreamChannel, self).__init__(remote_peer, local_peer=local_peer)
- self.bin_data_size = 0
- self.buf = bytearray(0x1000)
- self.buf_pos = 0
- self.buf_len = 0
-
- def get(self):
- pass
- def put(self, n):
- pass
-
- def getBuf(self, buf):
- i = 0
- l = len(buf)
- while i < l:
- b = self.get()
- if b < 0:
- if i == 0: return -1
- break
- buf[i] = b
- i += 1
- if i >= self.bin_data_size: break
- return i
-
- def putBuf(self, buf):
- for b in buf: self.put(b & 0xff)
-
- def read(self):
- while True:
- while self.buf_pos >= self.buf_len:
- self.buf_len = self.getBuf(self.buf)
- self.buf_pos = 0
- if self.buf_len < 0: return EOS
- res = self.buf[self.buf_pos] & 0xff
- self.buf_pos += 1
- if self.bin_data_size > 0:
- self.bin_data_size -= 1
- return res
- if res != ESC: return res
- while self.buf_pos >= self.buf_len:
- self.buf_len = self.getBuf(self.buf)
- self.buf_pos = 0
- if self.buf_len < 0: return EOS
- n = self.buf[self.buf_pos] & 0xff
- self.buf_pos += 1
- if n == 0: return ESC
- elif n == 1: return EOM
- elif n == 2: return EOS
- elif n == 3:
- for i in xrange(0, 100000, 7):
- while self.buf_pos >= self.buf_len:
- self.buf_len = self.getBuf(self.buf)
- self.buf_pos = 0
- if self.buf_len < 0: return EOS
- m = self.buf[self.buf_pos] & 0xff
- self.buf_pos += 1
- self.bin_data_size |= (m & 0x7f) << i
- if (m & 0x80) == 0: break
- else:
- if n < 0: return EOS
- assert False
-
- def writeByte(self, n):
- if n == ESC:
- self.put(ESC)
- self.put(0)
- elif n == EOM:
- self.put(ESC)
- self.put(1)
- elif n == EOS:
- self.put(ESC)
- self.put(2)
- else:
- assert n >= 0 and n <= 0xff
- self.put(n)
-
- def write(self, buf):
- t = type(buf)
- if t == types.IntType:
- self.writeByte(buf)
- return
- elif t == types.StringType:
- buf = bytearray(buf)
- if len(buf) > 32 and self.isZeroCopySupported():
- self.put(ESC)
- self.put(3)
- n = len(buf)
- while True:
- if n <= 0x7f:
- self.put(n)
- break
- self.put((n & 0x7f) | 0x80)
- n >>= 7
- self.putBuf(buf)
- else:
- for b in buf:
- n = b & 0xff
- self.put(n)
- if n == ESC:
- self.put(0)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+import types
+from AbstractChannel import AbstractChannel, EOS, EOM
+
+ESC = 3
+
+class StreamChannel(AbstractChannel):
+ """
+ Abstract channel implementation for stream oriented transport protocols.
+
+ StreamChannel implements communication link connecting two end points (peers).
+ The channel asynchronously transmits messages: commands, results and events.
+
+ StreamChannel uses escape sequences to represent End-Of-Message and End-Of-Stream markers.
+
+ Clients can subclass StreamChannel to support particular stream oriented transport (wire) protocol.
+ Also, see ChannelTCP for a concrete IChannel implementation that works on top of TCP sockets as a transport.
+ """
+
+ def __init__(self, remote_peer, local_peer=None):
+ super(StreamChannel, self).__init__(remote_peer, local_peer=local_peer)
+ self.bin_data_size = 0
+ self.buf = bytearray(0x1000)
+ self.buf_pos = 0
+ self.buf_len = 0
+
+ def get(self):
+ pass
+ def put(self, n):
+ pass
+
+ def getBuf(self, buf):
+ i = 0
+ l = len(buf)
+ while i < l:
+ b = self.get()
+ if b < 0:
+ if i == 0: return -1
+ break
+ buf[i] = b
+ i += 1
+ if i >= self.bin_data_size: break
+ return i
+
+ def putBuf(self, buf):
+ for b in buf: self.put(b & 0xff)
+
+ def read(self):
+ while True:
+ while self.buf_pos >= self.buf_len:
+ self.buf_len = self.getBuf(self.buf)
+ self.buf_pos = 0
+ if self.buf_len < 0: return EOS
+ res = self.buf[self.buf_pos] & 0xff
+ self.buf_pos += 1
+ if self.bin_data_size > 0:
+ self.bin_data_size -= 1
+ return res
+ if res != ESC: return res
+ while self.buf_pos >= self.buf_len:
+ self.buf_len = self.getBuf(self.buf)
+ self.buf_pos = 0
+ if self.buf_len < 0: return EOS
+ n = self.buf[self.buf_pos] & 0xff
+ self.buf_pos += 1
+ if n == 0: return ESC
+ elif n == 1: return EOM
+ elif n == 2: return EOS
+ elif n == 3:
+ for i in xrange(0, 100000, 7):
+ while self.buf_pos >= self.buf_len:
+ self.buf_len = self.getBuf(self.buf)
+ self.buf_pos = 0
+ if self.buf_len < 0: return EOS
+ m = self.buf[self.buf_pos] & 0xff
+ self.buf_pos += 1
+ self.bin_data_size |= (m & 0x7f) << i
+ if (m & 0x80) == 0: break
+ else:
+ if n < 0: return EOS
+ assert False
+
+ def writeByte(self, n):
+ if n == ESC:
+ self.put(ESC)
+ self.put(0)
+ elif n == EOM:
+ self.put(ESC)
+ self.put(1)
+ elif n == EOS:
+ self.put(ESC)
+ self.put(2)
+ else:
+ assert n >= 0 and n <= 0xff
+ self.put(n)
+
+ def write(self, buf):
+ t = type(buf)
+ if t == types.IntType:
+ self.writeByte(buf)
+ return
+ elif t == types.StringType:
+ buf = bytearray(buf)
+ if len(buf) > 32 and self.isZeroCopySupported():
+ self.put(ESC)
+ self.put(3)
+ n = len(buf)
+ while True:
+ if n <= 0x7f:
+ self.put(n)
+ break
+ self.put((n & 0x7f) | 0x80)
+ n >>= 7
+ self.putBuf(buf)
+ else:
+ for b in buf:
+ n = b & 0xff
+ self.put(n)
+ if n == ESC:
+ self.put(0)
diff --git a/python/src/tcf/channel/__init__.py b/python/src/tcf/channel/__init__.py
index c6c47974a..8fd0031d1 100644
--- a/python/src/tcf/channel/__init__.py
+++ b/python/src/tcf/channel/__init__.py
@@ -1,189 +1,189 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-import cStringIO, json, binascii, types
-
-# channel states
-STATE_OPENING = 0
-STATE_OPEN = 1
-STATE_CLOSED = 2
-
-class TraceListener(object):
- def onMessageReceived(self, type, token, service, name, data):
- pass
-
- def onMessageSent(self, type, token, service, name, data):
- pass
-
- def onChannelClosed(self, error):
- pass
-
-def Proxy(object):
- def onCommand(self, token, service, name, data):
- pass
-
- def onEvent(self, service, name, data):
- pass
-
- def onChannelClosed(self, error):
- pass
-
-_token_cnt = 0
-class Token(object):
- def __init__(self, id=None, listener=None):
- if id is None:
- global _token_cnt
- id = str(_token_cnt)
- _token_cnt += 1
- else:
- id = str(id)
- self.id = id
- self.listener = listener
- def getID(self):
- return self.id
- def getListener(self):
- return self.listener
- def cancel(self):
- return False
-
-class ChannelListener(object):
- """
- Channel listener interface.
- """
-
- def onChannelOpened(self):
- """
- Called when a channel is opened or redirected.
- """
- pass
-
- def onChannelClosed(self, error):
- """
- Called when channel closed. If it is closed because of an error,
- 'error' parameter will describe the error. 'error' is None if channel
- is closed normally by calling Channel.close().
- @param error - channel exception or None
- """
- pass
-
- def congestionLevel(self, level):
- """
- Notifies listeners about channel out-bound traffic congestion level changes.
- When level > 0 client should delay sending more messages.
- @param level - current congestion level
- """
- pass
-
-class EventListener(object):
- """
- A generic interface for service event listener.
- Services usually define a service specific event listener interface,
- which is implemented using this generic listener.
- Clients should user service specific listener interface,
- unless no such interface is defined.
- """
- svc_name = "<unknown>"
- def event(self, name, data):
- """
- Called when service event message is received
- @param name - event name
- @param data - event arguments encoded as bytearray
- """
- pass
-
-class CommandServer(object):
- """
- Command server interface.
- This interface is to be implemented by service providers.
- """
- def command(self, token, name, data):
- """
- Called every time a command is received from remote peer.
- @param token - command handle
- @param name - command name
- @param data - command arguments encoded into array of bytes
- """
- pass
-
-class CommandListener(object):
- """
- Command listener interface. Clients implement this interface to
- receive command results.
- """
- def progress(self, token, data):
- """
- Called when progress message (intermediate result) is received
- from remote peer.
- @param token - command handle
- @param data - progress message arguments encoded into array of bytes
- """
- pass
- def result(self, token, data):
- """
- Called when command result received from remote peer.
- @param token - command handle
- @param data - command result message arguments encoded into array of bytes
- """
- pass
- def terminated(self, token, error):
- """
- Called when command is terminated because communication channel was closed or
- command is not recognized by remote peer.
- @param token - command handle
- @param error - exception that forced the channel to close
- """
- pass
-
-def toJSONSequence(args):
- if args is None:
- return None
- buf = cStringIO.StringIO()
- for arg in args:
- json.dump(arg, buf, separators=(',', ':'), cls=TCFJSONEncoder)
- buf.write('\0')
- return buf.getvalue()
-
-def fromJSONSequence(bytes):
- if bytes[-1] == 0:
- del bytes[-1]
- str = bytes.decode("UTF-8")
- parts = str.split('\0')
- objects = []
- for part in parts:
- if part:
- objects.append(json.loads(part))
- else:
- objects.append(None)
- return objects
-
-def dumpJSONObject(object, buf):
- json.dump(object, buf, separators=(',', ':'), cls=TCFJSONEncoder)
-
-def toByteArray(data):
- if data is None: return None
- t = type(data)
- if t is bytearray: return data
- elif t is str:
- return binascii.a2b_base64(data)
- elif t is unicode:
- return binascii.a2b_base64(str(data))
- raise TypeError(str(t))
-
-class TCFJSONEncoder(json.JSONEncoder):
- def default(self, o):
- if isinstance(o, bytearray):
- return binascii.b2a_base64(o)[:-1]
- elif hasattr(o, '__json__'):
- return o.__json__()
- elif hasattr(o, '__iter__'):
- return tuple(o)
- else:
- json.JSONEncoder.default(self, o)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+import cStringIO, json, binascii, types
+
+# channel states
+STATE_OPENING = 0
+STATE_OPEN = 1
+STATE_CLOSED = 2
+
+class TraceListener(object):
+ def onMessageReceived(self, type, token, service, name, data):
+ pass
+
+ def onMessageSent(self, type, token, service, name, data):
+ pass
+
+ def onChannelClosed(self, error):
+ pass
+
+def Proxy(object):
+ def onCommand(self, token, service, name, data):
+ pass
+
+ def onEvent(self, service, name, data):
+ pass
+
+ def onChannelClosed(self, error):
+ pass
+
+_token_cnt = 0
+class Token(object):
+ def __init__(self, id=None, listener=None):
+ if id is None:
+ global _token_cnt
+ id = str(_token_cnt)
+ _token_cnt += 1
+ else:
+ id = str(id)
+ self.id = id
+ self.listener = listener
+ def getID(self):
+ return self.id
+ def getListener(self):
+ return self.listener
+ def cancel(self):
+ return False
+
+class ChannelListener(object):
+ """
+ Channel listener interface.
+ """
+
+ def onChannelOpened(self):
+ """
+ Called when a channel is opened or redirected.
+ """
+ pass
+
+ def onChannelClosed(self, error):
+ """
+ Called when channel closed. If it is closed because of an error,
+ 'error' parameter will describe the error. 'error' is None if channel
+ is closed normally by calling Channel.close().
+ @param error - channel exception or None
+ """
+ pass
+
+ def congestionLevel(self, level):
+ """
+ Notifies listeners about channel out-bound traffic congestion level changes.
+ When level > 0 client should delay sending more messages.
+ @param level - current congestion level
+ """
+ pass
+
+class EventListener(object):
+ """
+ A generic interface for service event listener.
+ Services usually define a service specific event listener interface,
+ which is implemented using this generic listener.
+ Clients should user service specific listener interface,
+ unless no such interface is defined.
+ """
+ svc_name = "<unknown>"
+ def event(self, name, data):
+ """
+ Called when service event message is received
+ @param name - event name
+ @param data - event arguments encoded as bytearray
+ """
+ pass
+
+class CommandServer(object):
+ """
+ Command server interface.
+ This interface is to be implemented by service providers.
+ """
+ def command(self, token, name, data):
+ """
+ Called every time a command is received from remote peer.
+ @param token - command handle
+ @param name - command name
+ @param data - command arguments encoded into array of bytes
+ """
+ pass
+
+class CommandListener(object):
+ """
+ Command listener interface. Clients implement this interface to
+ receive command results.
+ """
+ def progress(self, token, data):
+ """
+ Called when progress message (intermediate result) is received
+ from remote peer.
+ @param token - command handle
+ @param data - progress message arguments encoded into array of bytes
+ """
+ pass
+ def result(self, token, data):
+ """
+ Called when command result received from remote peer.
+ @param token - command handle
+ @param data - command result message arguments encoded into array of bytes
+ """
+ pass
+ def terminated(self, token, error):
+ """
+ Called when command is terminated because communication channel was closed or
+ command is not recognized by remote peer.
+ @param token - command handle
+ @param error - exception that forced the channel to close
+ """
+ pass
+
+def toJSONSequence(args):
+ if args is None:
+ return None
+ buf = cStringIO.StringIO()
+ for arg in args:
+ json.dump(arg, buf, separators=(',', ':'), cls=TCFJSONEncoder)
+ buf.write('\0')
+ return buf.getvalue()
+
+def fromJSONSequence(bytes):
+ if bytes[-1] == 0:
+ del bytes[-1]
+ str = bytes.decode("UTF-8")
+ parts = str.split('\0')
+ objects = []
+ for part in parts:
+ if part:
+ objects.append(json.loads(part))
+ else:
+ objects.append(None)
+ return objects
+
+def dumpJSONObject(object, buf):
+ json.dump(object, buf, separators=(',', ':'), cls=TCFJSONEncoder)
+
+def toByteArray(data):
+ if data is None: return None
+ t = type(data)
+ if t is bytearray: return data
+ elif t is str:
+ return binascii.a2b_base64(data)
+ elif t is unicode:
+ return binascii.a2b_base64(str(data))
+ raise TypeError(str(t))
+
+class TCFJSONEncoder(json.JSONEncoder):
+ def default(self, o):
+ if isinstance(o, bytearray):
+ return binascii.b2a_base64(o)[:-1]
+ elif hasattr(o, '__json__'):
+ return o.__json__()
+ elif hasattr(o, '__iter__'):
+ return tuple(o)
+ else:
+ json.JSONEncoder.default(self, o)
diff --git a/python/src/tcf/errors.py b/python/src/tcf/errors.py
index 79c2706a9..947590167 100644
--- a/python/src/tcf/errors.py
+++ b/python/src/tcf/errors.py
@@ -1,161 +1,161 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http:#www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-import cStringIO, time, types
-
-# Error report attribute names
-ERROR_CODE = "Code" # integer
-ERROR_TIME = "Time" # integer
-ERROR_SERVICE = "Service" # string
-ERROR_FORMAT = "Format" # string
-ERROR_PARAMS = "Params" # array
-ERROR_SEVERITY = "Severity" # integer
-ERROR_ALT_CODE = "AltCode" # integer
-ERROR_ALT_ORG = "AltOrg" # string
-ERROR_CAUSED_BY = "CausedBy" # object
-
-# Error severity codes
-SEVERITY_ERROR = 0
-SEVERITY_WARNING = 1
-SEVERITY_FATAL = 2
-
-# Error code ranges
-# Standard TCF code range */
-CODE_STD_MIN = 0
-CODE_STD_MAX = 0xffff
-
-# Service specific codes. Decoding requires service ID. */
-CODE_SERVICE_SPECIFIC_MIN = 0x10000
-CODE_SERVICE_SPECIFIC_MAX = 0x1ffff
-
-# Reserved codes - will never be used by the TCF standard */
-CODE_RESERVED_MIN = 0x20000
-CODE_RESERVED_MAX = 0x2ffff
-
-# Standard TCF error codes
-TCF_ERROR_OTHER = 1
-TCF_ERROR_JSON_SYNTAX = 2
-TCF_ERROR_PROTOCOL = 3
-TCF_ERROR_BUFFER_OVERFLOW = 4
-TCF_ERROR_CHANNEL_CLOSED = 5
-TCF_ERROR_COMMAND_CANCELLED = 6
-TCF_ERROR_UNKNOWN_PEER = 7
-TCF_ERROR_BASE64 = 8
-TCF_ERROR_EOF = 9
-TCF_ERROR_ALREADY_STOPPED = 10
-TCF_ERROR_ALREADY_EXITED = 11
-TCF_ERROR_ALREADY_RUNNING = 12
-TCF_ERROR_ALREADY_ATTACHED = 13
-TCF_ERROR_IS_RUNNING = 14
-TCF_ERROR_INV_DATA_SIZE = 15
-TCF_ERROR_INV_CONTEXT = 16
-TCF_ERROR_INV_ADDRESS = 17
-TCF_ERROR_INV_EXPRESSION = 18
-TCF_ERROR_INV_FORMAT = 19
-TCF_ERROR_INV_NUMBER = 20
-TCF_ERROR_INV_DWARF = 21
-TCF_ERROR_SYM_NOT_FOUND = 22
-TCF_ERROR_UNSUPPORTED = 23
-TCF_ERROR_INV_DATA_TYPE = 24
-TCF_ERROR_INV_COMMAND = 25
-TCF_ERROR_INV_TRANSPORT = 26
-TCF_ERROR_CACHE_MISS = 27
-TCF_ERROR_NOT_ACTIVE = 28
-
-_timestamp_format = "%Y-%m-%d %H:%M:%S"
-
-class ErrorReport(Exception):
- def __init__(self, msg, attrs):
- super(ErrorReport, self).__init__(msg)
- if type(attrs) is types.IntType:
- attrs = {
- ERROR_CODE : attrs,
- ERROR_TIME : int(time.time() * 1000),
- ERROR_FORMAT : msg,
- ERROR_SEVERITY : SEVERITY_ERROR
- }
- self.attrs = attrs
- caused_by = attrs.get(ERROR_CAUSED_BY)
- if caused_by:
- map = caused_by
- bf = cStringIO.StringIO()
- bf.write("TCF error report:")
- bf.write('\n')
- appendErrorProps(bf, map)
- self.caused_by = ErrorReport(bf.getvalue(), map)
-
- def getErrorCode(self):
- return self.attrs.get(ERROR_CODE) or 0
-
- def getAltCode(self):
- return self.attrs.get(ERROR_ALT_CODE) or 0
-
- def getAltOrg(self):
- return self.attrs.get(ERROR_ALT_ORG)
-
- def getAttributes(self):
- return self.attrs
-
-
-def toErrorString(data):
- if not data: return None
- map = data
- fmt = map.get(ERROR_FORMAT)
- if fmt:
- c = map.get(ERROR_PARAMS)
- if c: return fmt.format(c)
- return fmt
- code = map.get(ERROR_CODE)
- if code is not None:
- if code == TCF_ERROR_OTHER:
- alt_org = map.get(ERROR_ALT_ORG)
- alt_code = map.get(ERROR_ALT_CODE)
- if alt_org and alt_code:
- return "%s Error %d" % (alt_org, alt_code)
- return "TCF Error %d" % code
- return "Invalid error report format"
-
-def appendErrorProps(bf, map):
- timeVal = map.get(ERROR_TIME)
- code = map.get(ERROR_CODE)
- service = map.get(ERROR_SERVICE)
- severity = map.get(ERROR_SEVERITY)
- alt_code = map.get(ERROR_ALT_CODE)
- alt_org = map.get(ERROR_ALT_ORG)
- if timeVal:
- bf.write('\n')
- bf.write("Time: ")
- bf.write(time.strftime(_timestamp_format, time.localtime(timeVal/1000.)))
- if severity:
- bf.write('\n')
- bf.write("Severity: ")
- if severity == SEVERITY_ERROR: bf.write("Error")
- elif severity == SEVERITY_FATAL: bf.write("Fatal")
- elif severity == SEVERITY_WARNING: bf.write("Warning")
- else: bf.write("Unknown")
- bf.write('\n')
- bf.write("Error text: ")
- bf.write(toErrorString(map))
- bf.write('\n')
- bf.write("Error code: ")
- bf.write(str(code))
- if service:
- bf.write('\n')
- bf.write("Service: ")
- bf.write(service)
- if alt_code:
- bf.write('\n')
- bf.write("Alt code: ")
- bf.write(str(alt_code))
- if alt_org:
- bf.write('\n')
- bf.write("Alt org: ")
- bf.write(alt_org)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http:#www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+import cStringIO, time, types
+
+# Error report attribute names
+ERROR_CODE = "Code" # integer
+ERROR_TIME = "Time" # integer
+ERROR_SERVICE = "Service" # string
+ERROR_FORMAT = "Format" # string
+ERROR_PARAMS = "Params" # array
+ERROR_SEVERITY = "Severity" # integer
+ERROR_ALT_CODE = "AltCode" # integer
+ERROR_ALT_ORG = "AltOrg" # string
+ERROR_CAUSED_BY = "CausedBy" # object
+
+# Error severity codes
+SEVERITY_ERROR = 0
+SEVERITY_WARNING = 1
+SEVERITY_FATAL = 2
+
+# Error code ranges
+# Standard TCF code range */
+CODE_STD_MIN = 0
+CODE_STD_MAX = 0xffff
+
+# Service specific codes. Decoding requires service ID. */
+CODE_SERVICE_SPECIFIC_MIN = 0x10000
+CODE_SERVICE_SPECIFIC_MAX = 0x1ffff
+
+# Reserved codes - will never be used by the TCF standard */
+CODE_RESERVED_MIN = 0x20000
+CODE_RESERVED_MAX = 0x2ffff
+
+# Standard TCF error codes
+TCF_ERROR_OTHER = 1
+TCF_ERROR_JSON_SYNTAX = 2
+TCF_ERROR_PROTOCOL = 3
+TCF_ERROR_BUFFER_OVERFLOW = 4
+TCF_ERROR_CHANNEL_CLOSED = 5
+TCF_ERROR_COMMAND_CANCELLED = 6
+TCF_ERROR_UNKNOWN_PEER = 7
+TCF_ERROR_BASE64 = 8
+TCF_ERROR_EOF = 9
+TCF_ERROR_ALREADY_STOPPED = 10
+TCF_ERROR_ALREADY_EXITED = 11
+TCF_ERROR_ALREADY_RUNNING = 12
+TCF_ERROR_ALREADY_ATTACHED = 13
+TCF_ERROR_IS_RUNNING = 14
+TCF_ERROR_INV_DATA_SIZE = 15
+TCF_ERROR_INV_CONTEXT = 16
+TCF_ERROR_INV_ADDRESS = 17
+TCF_ERROR_INV_EXPRESSION = 18
+TCF_ERROR_INV_FORMAT = 19
+TCF_ERROR_INV_NUMBER = 20
+TCF_ERROR_INV_DWARF = 21
+TCF_ERROR_SYM_NOT_FOUND = 22
+TCF_ERROR_UNSUPPORTED = 23
+TCF_ERROR_INV_DATA_TYPE = 24
+TCF_ERROR_INV_COMMAND = 25
+TCF_ERROR_INV_TRANSPORT = 26
+TCF_ERROR_CACHE_MISS = 27
+TCF_ERROR_NOT_ACTIVE = 28
+
+_timestamp_format = "%Y-%m-%d %H:%M:%S"
+
+class ErrorReport(Exception):
+ def __init__(self, msg, attrs):
+ super(ErrorReport, self).__init__(msg)
+ if type(attrs) is types.IntType:
+ attrs = {
+ ERROR_CODE : attrs,
+ ERROR_TIME : int(time.time() * 1000),
+ ERROR_FORMAT : msg,
+ ERROR_SEVERITY : SEVERITY_ERROR
+ }
+ self.attrs = attrs
+ caused_by = attrs.get(ERROR_CAUSED_BY)
+ if caused_by:
+ map = caused_by
+ bf = cStringIO.StringIO()
+ bf.write("TCF error report:")
+ bf.write('\n')
+ appendErrorProps(bf, map)
+ self.caused_by = ErrorReport(bf.getvalue(), map)
+
+ def getErrorCode(self):
+ return self.attrs.get(ERROR_CODE) or 0
+
+ def getAltCode(self):
+ return self.attrs.get(ERROR_ALT_CODE) or 0
+
+ def getAltOrg(self):
+ return self.attrs.get(ERROR_ALT_ORG)
+
+ def getAttributes(self):
+ return self.attrs
+
+
+def toErrorString(data):
+ if not data: return None
+ map = data
+ fmt = map.get(ERROR_FORMAT)
+ if fmt:
+ c = map.get(ERROR_PARAMS)
+ if c: return fmt.format(c)
+ return fmt
+ code = map.get(ERROR_CODE)
+ if code is not None:
+ if code == TCF_ERROR_OTHER:
+ alt_org = map.get(ERROR_ALT_ORG)
+ alt_code = map.get(ERROR_ALT_CODE)
+ if alt_org and alt_code:
+ return "%s Error %d" % (alt_org, alt_code)
+ return "TCF Error %d" % code
+ return "Invalid error report format"
+
+def appendErrorProps(bf, map):
+ timeVal = map.get(ERROR_TIME)
+ code = map.get(ERROR_CODE)
+ service = map.get(ERROR_SERVICE)
+ severity = map.get(ERROR_SEVERITY)
+ alt_code = map.get(ERROR_ALT_CODE)
+ alt_org = map.get(ERROR_ALT_ORG)
+ if timeVal:
+ bf.write('\n')
+ bf.write("Time: ")
+ bf.write(time.strftime(_timestamp_format, time.localtime(timeVal/1000.)))
+ if severity:
+ bf.write('\n')
+ bf.write("Severity: ")
+ if severity == SEVERITY_ERROR: bf.write("Error")
+ elif severity == SEVERITY_FATAL: bf.write("Fatal")
+ elif severity == SEVERITY_WARNING: bf.write("Warning")
+ else: bf.write("Unknown")
+ bf.write('\n')
+ bf.write("Error text: ")
+ bf.write(toErrorString(map))
+ bf.write('\n')
+ bf.write("Error code: ")
+ bf.write(str(code))
+ if service:
+ bf.write('\n')
+ bf.write("Service: ")
+ bf.write(service)
+ if alt_code:
+ bf.write('\n')
+ bf.write("Alt code: ")
+ bf.write(str(alt_code))
+ if alt_org:
+ bf.write('\n')
+ bf.write("Alt org: ")
+ bf.write(alt_org)
diff --git a/python/src/tcf/peer.py b/python/src/tcf/peer.py
index f93092001..85d595d96 100644
--- a/python/src/tcf/peer.py
+++ b/python/src/tcf/peer.py
@@ -1,274 +1,274 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Both hosts and targets are represented by objects
-implementing IPeer interface. A peer can act as host or
-target depending on services it implements.
-List of currently known peers can be retrieved by
-calling Locator.getPeers()
-
-A TCF agent houses one or more service managers. A service manager has a one or more
-services to expose to the world. The service manager creates one or more peers
-to represent itself, one for every access path the agent is
-reachable by. For example, in agents accessible via TCP/IP, the
-service manger would create a peer for every subnet it wants to participate in.
-All peers of particular service manager represent identical sets of services.
-"""
-
-import os, time, json
-from tcf import protocol, transport, services
-from tcf.services import locator
-
-# Peer unique ID
-ATTR_ID = "ID"
-
-# Unique ID of service manager that is represented by this peer
-ATTR_SERVICE_MANAGER_ID = "ServiceManagerID"
-
-# Agent unique ID
-ATTR_AGENT_ID = "AgentID"
-
-# Peer name
-ATTR_NAME = "Name"
-
-# Name of the peer operating system
-ATTR_OS_NAME = "OSName"
-
-# Transport name, for example TCP, SSL
-ATTR_TRANSPORT_NAME = "TransportName"
-
-# If present, indicates that the peer can forward traffic to other peers
-ATTR_PROXY = "Proxy"
-
-# Host DNS name or IP address
-ATTR_IP_HOST = "Host"
-
-# Optional list of host aliases
-ATTR_IP_ALIASES = "Aliases"
-
-# Optional list of host addresses
-ATTR_IP_ADDRESSES = "Addresses"
-
-# IP port number, must be decimal number
-ATTR_IP_PORT = "Port"
-
-
-class Peer(object):
- def __init__(self, attrs):
- self.attrs = attrs
- def getAttributes(self):
- """@return map of peer attributes"""
- return self.attrs
-
- def getID(self):
- """@return peer unique ID, same as getAttributes().get(ATTR_ID)"""
- return self.attrs.get(ATTR_ID)
-
- def getServiceManagerID(self):
- """@return service manager unique ID, same as getAttributes().get(ATTR_SERVICE_MANAGER_ID)"""
- assert protocol.isDispatchThread()
- return self.attrs.get(ATTR_SERVICE_MANAGER_ID)
-
- def getAgentID(self):
- """@return agent unique ID, same as getAttributes().get(ATTR_AGENT_ID)"""
- assert protocol.isDispatchThread()
- return self.attrs.get(ATTR_AGENT_ID)
-
- def getName(self):
- """@return peer name, same as getAttributes().get(ATTR_NAME)"""
- return self.attrs.get(ATTR_NAME)
-
- def getOSName(self):
- """@return agent OS name, same as getAttributes().get(ATTR_OS_NAME)"""
- return self.attrs.get(ATTR_OS_NAME)
-
- def getTransportName(self):
- """@return transport name, same as getAttributes().get(ATTR_TRANSPORT_NAME)"""
- return self.attrs.get(ATTR_TRANSPORT_NAME)
-
- def openChannel(self):
- """Open channel to communicate with this peer.
- Note: the channel is not fully open yet when this method returns.
- Its state is channel.STATE_OPENING.
- Protocol.ChannelOpenListener and IChannel.IChannelListener listeners will be called when
- the channel will change state to open or closed.
- Clients are supposed to register IChannel.IChannelListener right after calling openChannel(), or,
- at least, in same dispatch cycle. For example:
- channel = peer.openChannel()
- channel.addChannelListener(...)
- """
- raise RuntimeError("Abstract method")
-
-
-class TransientPeer(Peer):
- """
- Transient implementation of IPeer interface.
- Objects of this class are not tracked by Locator service.
- See AbstractPeer for IPeer objects that should go into the Locator table.
- """
- def __init__(self, attrs):
- self.rw_attrs = {}
- self.rw_attrs.update(attrs)
- # TODO readonly map
- ro_attrs = {}
- ro_attrs.update(self.rw_attrs)
- super(TransientPeer, self).__init__(ro_attrs)
-
- def openChannel(self):
- return transport.openChannel(self)
-
-class LocalPeer(TransientPeer):
- """
- LocalPeer object represents local end-point of TCF communication channel.
- There should be exactly one such object in a TCF agent.
- The object can be used to open a loop-back communication channel that allows
- the agent to access its own services same way as remote services.
- Note that "local" here is relative to the agent, and not same as in "local host".
- """
- def __init__(self):
- super(LocalPeer, self).__init__(self.createAttributes())
-
- def createAttributes(self):
- attrs = {
- ATTR_ID : "TCFLocal",
- ATTR_SERVICE_MANAGER_ID : services.getServiceManagerID(),
- ATTR_AGENT_ID : protocol.getAgentID(),
- ATTR_NAME : "Local Peer",
- ATTR_OS_NAME : os.name,
- ATTR_TRANSPORT_NAME : "Loop"
- }
- return attrs;
-
-class AbstractPeer(TransientPeer):
- """
- Abstract implementation of IPeer interface.
- Objects of this class are stored in Locator service peer table.
- The class implements sending notification events to Locator listeners.
- See TransientPeer for IPeer objects that are not stored in the Locator table.
- """
-
- last_heart_beat_time = 0
-
- def __init__(self, attrs):
- super(AbstractPeer, self).__init__(attrs)
- assert protocol.isDispatchThread()
- id = self.getID()
- assert id
- peers = protocol.getLocator().getPeers()
- if isinstance(peers.get(id), RemotePeer):
- peers.get(id).dispose()
- assert id not in peers
- peers[id] = self
- self.sendPeerAddedEvent()
-
- def dispose(self):
- assert protocol.isDispatchThread()
- id = self.getID()
- assert id
- peers = protocol.getLocator().getPeers()
- assert peers.get(id) == self
- del peers[id]
- self.sendPeerRemovedEvent()
-
- def onChannelTerminated(self):
- # A channel to this peer was terminated:
- # not delaying next heart beat helps client to recover much faster.
- self.last_heart_beat_time = 0
-
- def updateAttributes(self, attrs):
- equ = True
- assert attrs.get(ATTR_ID) == self.rw_attrs.get(ATTR_ID)
- for key in self.rw_attrs.keys():
- if self.rw_attrs.get(key) != attrs.get(key):
- equ = False
- break
- for key in attrs.keys():
- if attrs.get(key) != self.rw_attrs.get(key):
- equ = False
- break
- timeVal = int(time.time() * 1000)
- if not equ:
- self.rw_attrs.clear()
- self.rw_attrs.update(attrs)
- for l in protocol.getLocator().getListeners():
- try:
- l.peerChanged(self)
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- try:
- args = [self.rw_attrs]
- protocol.sendEvent(locator.NAME, "peerChanged", json.dumps(args))
- except IOError as x:
- protocol.log("Locator: failed to send 'peerChanged' event", x)
- self.last_heart_beat_time = timeVal
- elif self.last_heart_beat_time + locator.DATA_RETENTION_PERIOD / 4 < timeVal:
- for l in protocol.getLocator().getListeners():
- try:
- l.peerHeartBeat(attrs.get(ATTR_ID))
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- try:
- args = [self.rw_attrs.get(ATTR_ID)]
- protocol.sendEvent(locator.NAME, "peerHeartBeat", json.dumps(args))
- except IOError as x:
- protocol.log("Locator: failed to send 'peerHeartBeat' event", x)
- self.last_heart_beat_time = timeVal
-
- def sendPeerAddedEvent(self):
- for l in protocol.getLocator().getListeners():
- try:
- l.peerAdded(self)
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- try:
- args = [self.rw_attrs]
- protocol.sendEvent(locator.NAME, "peerAdded", json.dumps(args))
- except IOError as x:
- protocol.log("Locator: failed to send 'peerAdded' event", x)
- self.last_heart_beat_time = int(time.time() * 1000)
-
- def sendPeerRemovedEvent(self):
- for l in protocol.getLocator().getListeners():
- try:
- l.peerRemoved(self.rw_attrs.get(ATTR_ID))
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- try:
- args = [self.rw_attrs.get(ATTR_ID)]
- protocol.sendEvent(locator.NAME, "peerRemoved", json.dumps(args))
- except IOError as x:
- protocol.log("Locator: failed to send 'peerRemoved' event", x)
-
-
-class RemotePeer(AbstractPeer):
- """
- RemotePeer objects represent TCF agents that Locator service discovered on local network.
- This includes both local host agents and remote host agents.
- Note that "remote peer" means any peer accessible over network,
- it does not imply the agent is running on a "remote host".
- If an agent binds multiple network interfaces or multiple ports, it can be represented by
- multiple RemotePeer objects - one per each network address/port combination.
- RemotePeer objects life cycle is managed by Locator service.
- """
-
- last_update_time = 0
-
- def __init__(self, attrs):
- super(RemotePeer, self).__init__(attrs)
- self.last_update_time = int(time.time() * 1000)
-
- def updateAttributes(self, attrs):
- super(RemotePeer, self).updateAttributes(attrs)
- self.last_update_time = int(time.time() * 1000)
-
- def getLastUpdateTime(self):
- return self.last_update_time
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Both hosts and targets are represented by objects
+implementing IPeer interface. A peer can act as host or
+target depending on services it implements.
+List of currently known peers can be retrieved by
+calling Locator.getPeers()
+
+A TCF agent houses one or more service managers. A service manager has a one or more
+services to expose to the world. The service manager creates one or more peers
+to represent itself, one for every access path the agent is
+reachable by. For example, in agents accessible via TCP/IP, the
+service manger would create a peer for every subnet it wants to participate in.
+All peers of particular service manager represent identical sets of services.
+"""
+
+import os, time, json
+from tcf import protocol, transport, services
+from tcf.services import locator
+
+# Peer unique ID
+ATTR_ID = "ID"
+
+# Unique ID of service manager that is represented by this peer
+ATTR_SERVICE_MANAGER_ID = "ServiceManagerID"
+
+# Agent unique ID
+ATTR_AGENT_ID = "AgentID"
+
+# Peer name
+ATTR_NAME = "Name"
+
+# Name of the peer operating system
+ATTR_OS_NAME = "OSName"
+
+# Transport name, for example TCP, SSL
+ATTR_TRANSPORT_NAME = "TransportName"
+
+# If present, indicates that the peer can forward traffic to other peers
+ATTR_PROXY = "Proxy"
+
+# Host DNS name or IP address
+ATTR_IP_HOST = "Host"
+
+# Optional list of host aliases
+ATTR_IP_ALIASES = "Aliases"
+
+# Optional list of host addresses
+ATTR_IP_ADDRESSES = "Addresses"
+
+# IP port number, must be decimal number
+ATTR_IP_PORT = "Port"
+
+
+class Peer(object):
+ def __init__(self, attrs):
+ self.attrs = attrs
+ def getAttributes(self):
+ """@return map of peer attributes"""
+ return self.attrs
+
+ def getID(self):
+ """@return peer unique ID, same as getAttributes().get(ATTR_ID)"""
+ return self.attrs.get(ATTR_ID)
+
+ def getServiceManagerID(self):
+ """@return service manager unique ID, same as getAttributes().get(ATTR_SERVICE_MANAGER_ID)"""
+ assert protocol.isDispatchThread()
+ return self.attrs.get(ATTR_SERVICE_MANAGER_ID)
+
+ def getAgentID(self):
+ """@return agent unique ID, same as getAttributes().get(ATTR_AGENT_ID)"""
+ assert protocol.isDispatchThread()
+ return self.attrs.get(ATTR_AGENT_ID)
+
+ def getName(self):
+ """@return peer name, same as getAttributes().get(ATTR_NAME)"""
+ return self.attrs.get(ATTR_NAME)
+
+ def getOSName(self):
+ """@return agent OS name, same as getAttributes().get(ATTR_OS_NAME)"""
+ return self.attrs.get(ATTR_OS_NAME)
+
+ def getTransportName(self):
+ """@return transport name, same as getAttributes().get(ATTR_TRANSPORT_NAME)"""
+ return self.attrs.get(ATTR_TRANSPORT_NAME)
+
+ def openChannel(self):
+ """Open channel to communicate with this peer.
+ Note: the channel is not fully open yet when this method returns.
+ Its state is channel.STATE_OPENING.
+ Protocol.ChannelOpenListener and IChannel.IChannelListener listeners will be called when
+ the channel will change state to open or closed.
+ Clients are supposed to register IChannel.IChannelListener right after calling openChannel(), or,
+ at least, in same dispatch cycle. For example:
+ channel = peer.openChannel()
+ channel.addChannelListener(...)
+ """
+ raise RuntimeError("Abstract method")
+
+
+class TransientPeer(Peer):
+ """
+ Transient implementation of IPeer interface.
+ Objects of this class are not tracked by Locator service.
+ See AbstractPeer for IPeer objects that should go into the Locator table.
+ """
+ def __init__(self, attrs):
+ self.rw_attrs = {}
+ self.rw_attrs.update(attrs)
+ # TODO readonly map
+ ro_attrs = {}
+ ro_attrs.update(self.rw_attrs)
+ super(TransientPeer, self).__init__(ro_attrs)
+
+ def openChannel(self):
+ return transport.openChannel(self)
+
+class LocalPeer(TransientPeer):
+ """
+ LocalPeer object represents local end-point of TCF communication channel.
+ There should be exactly one such object in a TCF agent.
+ The object can be used to open a loop-back communication channel that allows
+ the agent to access its own services same way as remote services.
+ Note that "local" here is relative to the agent, and not same as in "local host".
+ """
+ def __init__(self):
+ super(LocalPeer, self).__init__(self.createAttributes())
+
+ def createAttributes(self):
+ attrs = {
+ ATTR_ID : "TCFLocal",
+ ATTR_SERVICE_MANAGER_ID : services.getServiceManagerID(),
+ ATTR_AGENT_ID : protocol.getAgentID(),
+ ATTR_NAME : "Local Peer",
+ ATTR_OS_NAME : os.name,
+ ATTR_TRANSPORT_NAME : "Loop"
+ }
+ return attrs;
+
+class AbstractPeer(TransientPeer):
+ """
+ Abstract implementation of IPeer interface.
+ Objects of this class are stored in Locator service peer table.
+ The class implements sending notification events to Locator listeners.
+ See TransientPeer for IPeer objects that are not stored in the Locator table.
+ """
+
+ last_heart_beat_time = 0
+
+ def __init__(self, attrs):
+ super(AbstractPeer, self).__init__(attrs)
+ assert protocol.isDispatchThread()
+ id = self.getID()
+ assert id
+ peers = protocol.getLocator().getPeers()
+ if isinstance(peers.get(id), RemotePeer):
+ peers.get(id).dispose()
+ assert id not in peers
+ peers[id] = self
+ self.sendPeerAddedEvent()
+
+ def dispose(self):
+ assert protocol.isDispatchThread()
+ id = self.getID()
+ assert id
+ peers = protocol.getLocator().getPeers()
+ assert peers.get(id) == self
+ del peers[id]
+ self.sendPeerRemovedEvent()
+
+ def onChannelTerminated(self):
+ # A channel to this peer was terminated:
+ # not delaying next heart beat helps client to recover much faster.
+ self.last_heart_beat_time = 0
+
+ def updateAttributes(self, attrs):
+ equ = True
+ assert attrs.get(ATTR_ID) == self.rw_attrs.get(ATTR_ID)
+ for key in self.rw_attrs.keys():
+ if self.rw_attrs.get(key) != attrs.get(key):
+ equ = False
+ break
+ for key in attrs.keys():
+ if attrs.get(key) != self.rw_attrs.get(key):
+ equ = False
+ break
+ timeVal = int(time.time() * 1000)
+ if not equ:
+ self.rw_attrs.clear()
+ self.rw_attrs.update(attrs)
+ for l in protocol.getLocator().getListeners():
+ try:
+ l.peerChanged(self)
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ try:
+ args = [self.rw_attrs]
+ protocol.sendEvent(locator.NAME, "peerChanged", json.dumps(args))
+ except IOError as x:
+ protocol.log("Locator: failed to send 'peerChanged' event", x)
+ self.last_heart_beat_time = timeVal
+ elif self.last_heart_beat_time + locator.DATA_RETENTION_PERIOD / 4 < timeVal:
+ for l in protocol.getLocator().getListeners():
+ try:
+ l.peerHeartBeat(attrs.get(ATTR_ID))
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ try:
+ args = [self.rw_attrs.get(ATTR_ID)]
+ protocol.sendEvent(locator.NAME, "peerHeartBeat", json.dumps(args))
+ except IOError as x:
+ protocol.log("Locator: failed to send 'peerHeartBeat' event", x)
+ self.last_heart_beat_time = timeVal
+
+ def sendPeerAddedEvent(self):
+ for l in protocol.getLocator().getListeners():
+ try:
+ l.peerAdded(self)
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ try:
+ args = [self.rw_attrs]
+ protocol.sendEvent(locator.NAME, "peerAdded", json.dumps(args))
+ except IOError as x:
+ protocol.log("Locator: failed to send 'peerAdded' event", x)
+ self.last_heart_beat_time = int(time.time() * 1000)
+
+ def sendPeerRemovedEvent(self):
+ for l in protocol.getLocator().getListeners():
+ try:
+ l.peerRemoved(self.rw_attrs.get(ATTR_ID))
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ try:
+ args = [self.rw_attrs.get(ATTR_ID)]
+ protocol.sendEvent(locator.NAME, "peerRemoved", json.dumps(args))
+ except IOError as x:
+ protocol.log("Locator: failed to send 'peerRemoved' event", x)
+
+
+class RemotePeer(AbstractPeer):
+ """
+ RemotePeer objects represent TCF agents that Locator service discovered on local network.
+ This includes both local host agents and remote host agents.
+ Note that "remote peer" means any peer accessible over network,
+ it does not imply the agent is running on a "remote host".
+ If an agent binds multiple network interfaces or multiple ports, it can be represented by
+ multiple RemotePeer objects - one per each network address/port combination.
+ RemotePeer objects life cycle is managed by Locator service.
+ """
+
+ last_update_time = 0
+
+ def __init__(self, attrs):
+ super(RemotePeer, self).__init__(attrs)
+ self.last_update_time = int(time.time() * 1000)
+
+ def updateAttributes(self, attrs):
+ super(RemotePeer, self).updateAttributes(attrs)
+ self.last_update_time = int(time.time() * 1000)
+
+ def getLastUpdateTime(self):
+ return self.last_update_time
diff --git a/python/src/tcf/services/__init__.py b/python/src/tcf/services/__init__.py
index 9cad2fa40..1432a02b0 100644
--- a/python/src/tcf/services/__init__.py
+++ b/python/src/tcf/services/__init__.py
@@ -1,127 +1,127 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-import threading, collections
-from tcf import protocol
-
-_providers = []
-_lock = threading.RLock()
-
-class ServiceProvider(object):
- """
- Clients can implement this abstract class if they want to provide implementation of a local service or
- remote service proxy.
- """
- def getLocalService(self, channel):
- pass
- def getServiceProxy(self, channel, service_name):
- pass
-
-def addServiceProvider(provider):
- with _lock:
- _providers.append(provider)
-
-def removeServiceProvider(provider):
- with _lock:
- _providers.remove(provider)
-
-def onChannelCreated(channel, services_by_name):
- with _lock:
- # TODO ZeroCopy support is incomplete
-# zero_copy = ZeroCopy()
-# services_by_name[zero_copy.getName()] = zero_copy
- for provider in _providers:
- try:
- arr = provider.getLocalService(channel)
- if not arr: continue
- for service in arr:
- if service.getName() in services_by_name: continue
- services_by_name[service.getName()] = service
- except Exception as x:
- protocol.log("Error calling TCF service provider", x);
-
-def onChannelOpened(channel, service_names, services_by_name):
- with _lock:
- for name in service_names:
- for provider in _providers:
- try:
- service = provider.getServiceProxy(channel, name)
- if not service: continue
- services_by_name[name] = service
- break
- except Exception as x:
- protocol.log("Error calling TCF service provider", x)
- if name in services_by_name: continue
- services_by_name[name] = GenericProxy(channel, name)
-
-def getServiceManagerID():
- # In current implementation ServiceManager is a singleton,
- # so its ID is same as agent ID.
- return protocol.getAgentID()
-
-class GenericCallback(object):
- def __init__(self, callback):
- self.callback = callback
- def __getattr__(self, attr):
- if attr.startswith("done"):
- return self.callback
-
-class Service(object):
- def getName(self):
- raise NotImplementedError("Abstract method")
- def __str__(self):
- return self.getName()
- def _makeCallback(self, done):
- if isinstance(done, collections.Callable):
- return GenericCallback(done)
- return done
-
-class ZeroCopy(Service):
- def getName(self):
- return "ZeroCopy"
-
-class GenericProxy(Service):
- """
- * Objects of GenericProxy class represent remote services, which don't
- * have a proxy class defined for them.
- * Clients still can use such services, but framework will not provide
- * service specific utility methods for message formatting and parsing.
- """
- def __init__(self, channel, name):
- self.__channel = channel
- self.name = name
- def getName(self):
- return self.name
- def getChannel(self):
- return self.__channel
-
-class DefaultServiceProvider(ServiceProvider):
- package_base = "tcf.services.remote"
- def getLocalService(self, channel):
- # TODO DiagnosticsService
- #return [DiagnosticsService(channel)]
- return []
- def getServiceProxy(self, channel, service_name):
- service = None
- try:
- clsName = service_name + "Proxy"
- package = self.package_base + "." + clsName
- clsModule = __import__(package, fromlist=[clsName], globals=globals())
- cls = clsModule.__dict__.get(clsName)
- service = cls(channel)
- assert service_name == service.getName()
- except ImportError:
- pass
- except Exception as x:
- protocol.log("Cannot instantiate service proxy for "+service_name, x)
- return service
-
-addServiceProvider(DefaultServiceProvider())
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+import threading, collections
+from tcf import protocol
+
+_providers = []
+_lock = threading.RLock()
+
+class ServiceProvider(object):
+ """
+ Clients can implement this abstract class if they want to provide implementation of a local service or
+ remote service proxy.
+ """
+ def getLocalService(self, channel):
+ pass
+ def getServiceProxy(self, channel, service_name):
+ pass
+
+def addServiceProvider(provider):
+ with _lock:
+ _providers.append(provider)
+
+def removeServiceProvider(provider):
+ with _lock:
+ _providers.remove(provider)
+
+def onChannelCreated(channel, services_by_name):
+ with _lock:
+ # TODO ZeroCopy support is incomplete
+# zero_copy = ZeroCopy()
+# services_by_name[zero_copy.getName()] = zero_copy
+ for provider in _providers:
+ try:
+ arr = provider.getLocalService(channel)
+ if not arr: continue
+ for service in arr:
+ if service.getName() in services_by_name: continue
+ services_by_name[service.getName()] = service
+ except Exception as x:
+ protocol.log("Error calling TCF service provider", x);
+
+def onChannelOpened(channel, service_names, services_by_name):
+ with _lock:
+ for name in service_names:
+ for provider in _providers:
+ try:
+ service = provider.getServiceProxy(channel, name)
+ if not service: continue
+ services_by_name[name] = service
+ break
+ except Exception as x:
+ protocol.log("Error calling TCF service provider", x)
+ if name in services_by_name: continue
+ services_by_name[name] = GenericProxy(channel, name)
+
+def getServiceManagerID():
+ # In current implementation ServiceManager is a singleton,
+ # so its ID is same as agent ID.
+ return protocol.getAgentID()
+
+class GenericCallback(object):
+ def __init__(self, callback):
+ self.callback = callback
+ def __getattr__(self, attr):
+ if attr.startswith("done"):
+ return self.callback
+
+class Service(object):
+ def getName(self):
+ raise NotImplementedError("Abstract method")
+ def __str__(self):
+ return self.getName()
+ def _makeCallback(self, done):
+ if isinstance(done, collections.Callable):
+ return GenericCallback(done)
+ return done
+
+class ZeroCopy(Service):
+ def getName(self):
+ return "ZeroCopy"
+
+class GenericProxy(Service):
+ """
+ * Objects of GenericProxy class represent remote services, which don't
+ * have a proxy class defined for them.
+ * Clients still can use such services, but framework will not provide
+ * service specific utility methods for message formatting and parsing.
+ """
+ def __init__(self, channel, name):
+ self.__channel = channel
+ self.name = name
+ def getName(self):
+ return self.name
+ def getChannel(self):
+ return self.__channel
+
+class DefaultServiceProvider(ServiceProvider):
+ package_base = "tcf.services.remote"
+ def getLocalService(self, channel):
+ # TODO DiagnosticsService
+ #return [DiagnosticsService(channel)]
+ return []
+ def getServiceProxy(self, channel, service_name):
+ service = None
+ try:
+ clsName = service_name + "Proxy"
+ package = self.package_base + "." + clsName
+ clsModule = __import__(package, fromlist=[clsName], globals=globals())
+ cls = clsModule.__dict__.get(clsName)
+ service = cls(channel)
+ assert service_name == service.getName()
+ except ImportError:
+ pass
+ except Exception as x:
+ protocol.log("Cannot instantiate service proxy for "+service_name, x)
+ return service
+
+addServiceProvider(DefaultServiceProvider())
diff --git a/python/src/tcf/services/breakpoints.py b/python/src/tcf/services/breakpoints.py
index 0ca646119..23a5d2d25 100644
--- a/python/src/tcf/services/breakpoints.py
+++ b/python/src/tcf/services/breakpoints.py
@@ -1,313 +1,313 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Breakpoint is represented by unique identifier and set of properties.
-Breakpoint identifier (String id) needs to be unique across all hosts and targets.
-
-Breakpoint properties (Map<String,Object>) is extendible collection of named attributes,
-which define breakpoint location and behavior. This module defines some common
-attribute names (see PROP_*), host tools and target agents may support additional attributes.
-
-For each breakpoint a target agent maintains another extendible collection of named attributes:
-breakpoint status (Map<String,Object>, see STATUS_*). While breakpoint properties are
-persistent and represent user input, breakpoint status reflects dynamic target agent reports
-about breakpoint current state, like actual addresses where breakpoint is planted or planting errors.
-"""
-
-from tcf import services
-
-# Service name.
-NAME = "Breakpoints"
-
-# Breakpoint property names.
-PROP_ID = "ID" # String
-PROP_ENABLED = "Enabled" # Boolean
-PROP_TYPE = "BreakpointType" # String
-PROP_CONTEXTNAMES = "ContextNames" # Array
-PROP_CONTEXTIDS = "ContextIds" # Array
-PROP_EXECUTABLEPATHS = "ExecPaths" # Array
-PROP_LOCATION = "Location" # String
-PROP_SIZE = "Size" # Number
-PROP_ACCESSMODE = "AccessMode" # Number
-PROP_FILE = "File" # String
-PROP_LINE = "Line" # Number
-PROP_COLUMN = "Column" # Number
-PROP_PATTERN = "MaskValue" # Number
-PROP_MASK = "Mask" # Number
-PROP_STOP_GROUP = "StopGroup" # Array
-PROP_IGNORECOUNT = "IgnoreCount" # Number
-PROP_TIME = "Time" # Number
-PROP_SCALE = "TimeScale" # String
-PROP_UNITS = "TimeUnits" # String
-PROP_CONDITION = "Condition" # String
-PROP_TEMPORARY = "Temporary" # Boolean
-
-# BreakpointType values
-TYPE_SOFTWARE = "Software",
-TYPE_HARDWARE = "Hardware"
-TYPE_AUTO = "Auto"
-
-# AccessMode values
-ACCESSMODE_READ = 0x01
-ACCESSMODE_WRITE = 0x02
-ACCESSMODE_EXECUTE = 0x04
-ACCESSMODE_CHANGE = 0x08
-
-# TimeScale values
-TIMESCALE_RELATIVE = "Relative"
-TIMESCALE_ABSOLUTE = "Absolute"
-
-# TimeUnits values
-TIMEUNIT_NSECS = "Nanoseconds"
-TIMEUNIT_CYCLE_COUNT = "CycleCount"
-TIMEUNIT_INSTRUCTION_COUNT = "InstructionCount"
-
-# Breakpoint status field names.
-STATUS_INSTANCES = "Instances" # Array of Map<String,Object>
-STATUS_ERROR= "Error" # String
-STATUS_FILE = "File" # String
-STATUS_LINE = "Line" # Number
-STATUS_COLUMN = "Column" # Number
-
-# Breakpoint instance field names.
-INSTANCE_ERROR = "Error" # String
-INSTANCE_CONTEXT = "LocationContext" # String
-INSTANCE_ADDRESS = "Address" # Number
-
-# Breakpoint service capabilities.
-CAPABILITY_CONTEXT_ID = "ID" # String
-CAPABILITY_HAS_CHILDREN = "HasChildren" # Boolean
-CAPABILITY_LOCATION = "Location" # Boolean
-CAPABILITY_CONDITION = "Condition" # Boolean
-CAPABILITY_FILE_LINE = "FileLine" # Boolean
-CAPABILITY_CONTEXTIDS = "ContextIds" # Boolean
-CAPABILITY_STOP_GROUP = "StopGroup" # Boolean
-CAPABILITY_IGNORECOUNT = "IgnoreCount" # Boolean
-CAPABILITY_ACCESSMODE = "AccessMode" # Number
-
-class BreakpointsService(services.Service):
- def getName(self):
- return NAME
-
- def set(self, properties, done):
- """
- Download breakpoints data to target agent.
- The command is intended to be used only to initialize target breakpoints table
- when communication channel is open. After that, host should
- notify target about (incremental) changes in breakpoint data by sending
- add, change and remove commands.
-
- @param properties - array of breakpoints.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneCommand
- """
- raise NotImplementedError("Abstract method")
-
- def add(self, properties, done):
- """
- Called when breakpoint is added into breakpoints table.
- @param properties - breakpoint properties.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneCommand
- """
- raise NotImplementedError("Abstract method")
-
- def change(self, properties, done):
- """
- Called when breakpoint properties are changed.
- @param properties - breakpoint properties.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneCommand
- """
- raise NotImplementedError("Abstract method")
-
- def enable(self, ids, done):
- """
- Tell target to change (only) PROP_ENABLED breakpoint property to 'true'.
- @param ids - array of enabled breakpoint identifiers.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneCommand
- """
- raise NotImplementedError("Abstract method")
-
- def disable(self, ids, done):
- """
- Tell target to change (only) PROP_ENABLED breakpoint property to 'false'.
- @param ids - array of disabled breakpoint identifiers.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneCommand
- """
- raise NotImplementedError("Abstract method")
-
- def remove(self, ids, done):
- """
- Tell target to remove breakpoints.
- @param id - unique breakpoint identifier.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneCommand
- """
- raise NotImplementedError("Abstract method")
-
- def getIDs(self, done):
- """
- Upload IDs of breakpoints known to target agent.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneGetIDs
- """
- raise NotImplementedError("Abstract method")
-
- def getProperties(self, id, done):
- """
- Upload properties of given breakpoint from target agent breakpoint table.
- @param id - unique breakpoint identifier.
- @param done - command result call back object.
- @see DoneGetProperties
- """
- raise NotImplementedError("Abstract method")
-
- def getStatus(self, id, done):
- """
- Upload status of given breakpoint from target agent.
- @param id - unique breakpoint identifier.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneGetStatus
- """
- raise NotImplementedError("Abstract method")
-
- def getCapabilities(self, id, done):
- """
- Report breakpoint service capabilities to clients so they
- can adjust to different implementations of the service.
- When called with a None ("") context ID the global capabilities are returned,
- otherwise context specific capabilities are returned. A special capability
- property is used to indicate that all child contexts have the same
- capabilities.
- @param id - a context ID or None.
- @param done - command result call back object.
- @return - pending command handle.
- @see DoneGetCapabilities
- """
- raise NotImplementedError("Abstract method")
-
- def addListener(self, listener):
- """
- Add breakpoints service event listener.
- @param listener - object that implements BreakpointsListener interface.
- """
- raise NotImplementedError("Abstract method")
-
- def removeListener(self, listener):
- """
- Remove breakpoints service event listener.
- @param listener - object that implements BreakpointsListener interface.
- """
- raise NotImplementedError("Abstract method")
-
-
-class DoneCommand(object):
- "Call back interface for breakpoint service commands."
- def doneCommand(self, token, error):
- """
- Called when command is done.
- @param token - command handle.
- @param error - error object or None.
- """
- pass
-
-class DoneGetIDs(object):
- "Call back interface for 'getIDs' command."
- def doneGetIDs(self, token, error, ids):
- """
- Called when 'getIDs' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param ids - IDs of breakpoints known to target agent.
- """
- pass
-
-class DoneGetProperties(object):
- "Call back interface for 'getProperties' command."
- def doneGetProperties(self, token, error, properties):
- """
- Called when 'getProperties' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param properties - properties of the breakpoint.
- """
- pass
-
-class DoneGetStatus(object):
- "Call back interface for 'getStatus' command."
- def doneGetStatus(self, token, error, status):
- """
- Called when 'getStatus' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param status - status of the breakpoint.
- """
- pass
-
-class DoneGetCapabilities(object):
- "Call back interface for 'getCapabilities' command."
- def doneGetCapabilities(self, token, error, capabilities):
- """
- Called when 'getCapabilities' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param capabilities - breakpoints service capabilities description.
- """
- pass
-
-class BreakpointsListener(object):
- """
- Breakpoints service events listener.
- Note that contextAdded, contextChanged and contextRemoved events carry exactly same set
- of breakpoint properties that was sent by a client to a target. The purpose of these events is to
- let all clients know about breakpoints that were created by other clients.
- """
-
- def breakpointStatusChanged(self, id, status):
- """
- Called when breakpoint status changes.
- @param id - unique breakpoint identifier.
- @param status - breakpoint status.
- """
- pass
-
- def contextAdded(self, bps):
- """
- Called when a new breakpoints are added.
- @param bps - array of breakpoints.
- """
- pass
-
- def contextChanged(self, bps):
- """
- Called when breakpoint properties change.
- @param bps - array of breakpoints.
- """
- pass
-
- def contextRemoved(self, ids):
- """
- Called when breakpoints are removed .
- @param ids - array of breakpoint IDs.
- """
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Breakpoint is represented by unique identifier and set of properties.
+Breakpoint identifier (String id) needs to be unique across all hosts and targets.
+
+Breakpoint properties (Map<String,Object>) is extendible collection of named attributes,
+which define breakpoint location and behavior. This module defines some common
+attribute names (see PROP_*), host tools and target agents may support additional attributes.
+
+For each breakpoint a target agent maintains another extendible collection of named attributes:
+breakpoint status (Map<String,Object>, see STATUS_*). While breakpoint properties are
+persistent and represent user input, breakpoint status reflects dynamic target agent reports
+about breakpoint current state, like actual addresses where breakpoint is planted or planting errors.
+"""
+
+from tcf import services
+
+# Service name.
+NAME = "Breakpoints"
+
+# Breakpoint property names.
+PROP_ID = "ID" # String
+PROP_ENABLED = "Enabled" # Boolean
+PROP_TYPE = "BreakpointType" # String
+PROP_CONTEXTNAMES = "ContextNames" # Array
+PROP_CONTEXTIDS = "ContextIds" # Array
+PROP_EXECUTABLEPATHS = "ExecPaths" # Array
+PROP_LOCATION = "Location" # String
+PROP_SIZE = "Size" # Number
+PROP_ACCESSMODE = "AccessMode" # Number
+PROP_FILE = "File" # String
+PROP_LINE = "Line" # Number
+PROP_COLUMN = "Column" # Number
+PROP_PATTERN = "MaskValue" # Number
+PROP_MASK = "Mask" # Number
+PROP_STOP_GROUP = "StopGroup" # Array
+PROP_IGNORECOUNT = "IgnoreCount" # Number
+PROP_TIME = "Time" # Number
+PROP_SCALE = "TimeScale" # String
+PROP_UNITS = "TimeUnits" # String
+PROP_CONDITION = "Condition" # String
+PROP_TEMPORARY = "Temporary" # Boolean
+
+# BreakpointType values
+TYPE_SOFTWARE = "Software",
+TYPE_HARDWARE = "Hardware"
+TYPE_AUTO = "Auto"
+
+# AccessMode values
+ACCESSMODE_READ = 0x01
+ACCESSMODE_WRITE = 0x02
+ACCESSMODE_EXECUTE = 0x04
+ACCESSMODE_CHANGE = 0x08
+
+# TimeScale values
+TIMESCALE_RELATIVE = "Relative"
+TIMESCALE_ABSOLUTE = "Absolute"
+
+# TimeUnits values
+TIMEUNIT_NSECS = "Nanoseconds"
+TIMEUNIT_CYCLE_COUNT = "CycleCount"
+TIMEUNIT_INSTRUCTION_COUNT = "InstructionCount"
+
+# Breakpoint status field names.
+STATUS_INSTANCES = "Instances" # Array of Map<String,Object>
+STATUS_ERROR= "Error" # String
+STATUS_FILE = "File" # String
+STATUS_LINE = "Line" # Number
+STATUS_COLUMN = "Column" # Number
+
+# Breakpoint instance field names.
+INSTANCE_ERROR = "Error" # String
+INSTANCE_CONTEXT = "LocationContext" # String
+INSTANCE_ADDRESS = "Address" # Number
+
+# Breakpoint service capabilities.
+CAPABILITY_CONTEXT_ID = "ID" # String
+CAPABILITY_HAS_CHILDREN = "HasChildren" # Boolean
+CAPABILITY_LOCATION = "Location" # Boolean
+CAPABILITY_CONDITION = "Condition" # Boolean
+CAPABILITY_FILE_LINE = "FileLine" # Boolean
+CAPABILITY_CONTEXTIDS = "ContextIds" # Boolean
+CAPABILITY_STOP_GROUP = "StopGroup" # Boolean
+CAPABILITY_IGNORECOUNT = "IgnoreCount" # Boolean
+CAPABILITY_ACCESSMODE = "AccessMode" # Number
+
+class BreakpointsService(services.Service):
+ def getName(self):
+ return NAME
+
+ def set(self, properties, done):
+ """
+ Download breakpoints data to target agent.
+ The command is intended to be used only to initialize target breakpoints table
+ when communication channel is open. After that, host should
+ notify target about (incremental) changes in breakpoint data by sending
+ add, change and remove commands.
+
+ @param properties - array of breakpoints.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneCommand
+ """
+ raise NotImplementedError("Abstract method")
+
+ def add(self, properties, done):
+ """
+ Called when breakpoint is added into breakpoints table.
+ @param properties - breakpoint properties.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneCommand
+ """
+ raise NotImplementedError("Abstract method")
+
+ def change(self, properties, done):
+ """
+ Called when breakpoint properties are changed.
+ @param properties - breakpoint properties.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneCommand
+ """
+ raise NotImplementedError("Abstract method")
+
+ def enable(self, ids, done):
+ """
+ Tell target to change (only) PROP_ENABLED breakpoint property to 'true'.
+ @param ids - array of enabled breakpoint identifiers.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneCommand
+ """
+ raise NotImplementedError("Abstract method")
+
+ def disable(self, ids, done):
+ """
+ Tell target to change (only) PROP_ENABLED breakpoint property to 'false'.
+ @param ids - array of disabled breakpoint identifiers.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneCommand
+ """
+ raise NotImplementedError("Abstract method")
+
+ def remove(self, ids, done):
+ """
+ Tell target to remove breakpoints.
+ @param id - unique breakpoint identifier.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneCommand
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getIDs(self, done):
+ """
+ Upload IDs of breakpoints known to target agent.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneGetIDs
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getProperties(self, id, done):
+ """
+ Upload properties of given breakpoint from target agent breakpoint table.
+ @param id - unique breakpoint identifier.
+ @param done - command result call back object.
+ @see DoneGetProperties
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getStatus(self, id, done):
+ """
+ Upload status of given breakpoint from target agent.
+ @param id - unique breakpoint identifier.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneGetStatus
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getCapabilities(self, id, done):
+ """
+ Report breakpoint service capabilities to clients so they
+ can adjust to different implementations of the service.
+ When called with a None ("") context ID the global capabilities are returned,
+ otherwise context specific capabilities are returned. A special capability
+ property is used to indicate that all child contexts have the same
+ capabilities.
+ @param id - a context ID or None.
+ @param done - command result call back object.
+ @return - pending command handle.
+ @see DoneGetCapabilities
+ """
+ raise NotImplementedError("Abstract method")
+
+ def addListener(self, listener):
+ """
+ Add breakpoints service event listener.
+ @param listener - object that implements BreakpointsListener interface.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def removeListener(self, listener):
+ """
+ Remove breakpoints service event listener.
+ @param listener - object that implements BreakpointsListener interface.
+ """
+ raise NotImplementedError("Abstract method")
+
+
+class DoneCommand(object):
+ "Call back interface for breakpoint service commands."
+ def doneCommand(self, token, error):
+ """
+ Called when command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ """
+ pass
+
+class DoneGetIDs(object):
+ "Call back interface for 'getIDs' command."
+ def doneGetIDs(self, token, error, ids):
+ """
+ Called when 'getIDs' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param ids - IDs of breakpoints known to target agent.
+ """
+ pass
+
+class DoneGetProperties(object):
+ "Call back interface for 'getProperties' command."
+ def doneGetProperties(self, token, error, properties):
+ """
+ Called when 'getProperties' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param properties - properties of the breakpoint.
+ """
+ pass
+
+class DoneGetStatus(object):
+ "Call back interface for 'getStatus' command."
+ def doneGetStatus(self, token, error, status):
+ """
+ Called when 'getStatus' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param status - status of the breakpoint.
+ """
+ pass
+
+class DoneGetCapabilities(object):
+ "Call back interface for 'getCapabilities' command."
+ def doneGetCapabilities(self, token, error, capabilities):
+ """
+ Called when 'getCapabilities' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param capabilities - breakpoints service capabilities description.
+ """
+ pass
+
+class BreakpointsListener(object):
+ """
+ Breakpoints service events listener.
+ Note that contextAdded, contextChanged and contextRemoved events carry exactly same set
+ of breakpoint properties that was sent by a client to a target. The purpose of these events is to
+ let all clients know about breakpoints that were created by other clients.
+ """
+
+ def breakpointStatusChanged(self, id, status):
+ """
+ Called when breakpoint status changes.
+ @param id - unique breakpoint identifier.
+ @param status - breakpoint status.
+ """
+ pass
+
+ def contextAdded(self, bps):
+ """
+ Called when a new breakpoints are added.
+ @param bps - array of breakpoints.
+ """
+ pass
+
+ def contextChanged(self, bps):
+ """
+ Called when breakpoint properties change.
+ @param bps - array of breakpoints.
+ """
+ pass
+
+ def contextRemoved(self, ids):
+ """
+ Called when breakpoints are removed .
+ @param ids - array of breakpoint IDs.
+ """
+ pass
diff --git a/python/src/tcf/services/diagnostics.py b/python/src/tcf/services/diagnostics.py
index 54bfa2050..d16ae51df 100644
--- a/python/src/tcf/services/diagnostics.py
+++ b/python/src/tcf/services/diagnostics.py
@@ -1,285 +1,285 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-This is an optional service that can be implemented by a peer.
-If implemented, the service can be used for testing of the peer and
-communication channel functionality and reliability.
-"""
-
-from tcf import services
-
-NAME = "Diagnostics"
-
-class DiagnosticsService(services.Service):
- def getName(self):
- return NAME
-
- def echo(self, s, done):
- """
- 'echo' command result returns same string that was given as command argument.
- The command is used to test communication channel ability to transmit arbitrary strings in
- both directions.
- @param s - any string.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def echoFP(self, n, done):
- """
- 'echoFP' command result returns same floating point number that was given as command argument.
- The command is used to test communication channel ability to transmit arbitrary floating point numbers in
- both directions.
- @param n - any floating point number.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def echoERR(self, error, done):
- """
- 'echoERR' command result returns same error report that was given as command argument.
- The command is used to test remote agent ability to receive and transmit TCF error reports.
- @param error - an error object.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def getTestList(self, done):
- """
- Get list of test names that are implemented by the service.
- Clients can request remote peer to run a test from the list.
- When started, a test performs a predefined set actions.
- Nature of test actions is uniquely identified by test name.
- Exact description of test actions is a contract between client and remote peer,
- and it is not part of Diagnostics service specifications.
- Clients should not attempt to run a test if they don't recognize the test name.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def runTest(self, name, done):
- """
- Run a test. When started, a test performs a predefined set actions.
- Nature of test actions is uniquely identified by test name.
- Running test usually has associated execution context ID.
- Depending on the test, the ID can be used with services RunControl and/or Processes services to control
- test execution, and to obtain test results.
- @param name - test name
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def cancelTest(self, context_id, done):
- """
- Cancel execution of a test.
- @param context_id - text execution context ID.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def getSymbol(self, context_id, symbol_name, done):
- """
- Get information about a symbol in text execution context.
- @param context_id
- @param symbol_name
- @param done
- @return
- """
- return NotImplementedError("Abstract method")
-
- def createTestStreams(self, inp_buf_size, out_buf_size, done):
- """
- Create a pair of virtual streams, @see IStreams service.
- Remote ends of the streams are connected, so any data sent into 'inp' stream
- will become for available for reading from 'out' stream.
- The command is used for testing virtual streams.
- @param inp_buf_size - buffer size in bytes of the input stream.
- @param out_buf_size - buffer size in bytes of the output stream.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def disposeTestStream(self, id, done):
- """
- Dispose a virtual stream that was created by 'createTestStreams' command.
- @param id - the stream ID.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def not_implemented_command(self, done):
- """
- Send a command that is not implemented by peer.
- Used to test handling of 'N' messages by communication channel.
- @param done - command result call back object.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
-
-class DoneEcho(object):
- """
- Call back interface for 'echo' command.
- """
- def doneEcho(self, token, error, s):
- """
- Called when 'echo' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param s - same string as the command argument.
- """
- pass
-
-class DoneEchoFP(object):
- """
- Call back interface for 'echoFP' command.
- """
- def doneEchoFP(self, token, error, n):
- """
- Called when 'echoFP' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param n - same number as the command argument.
- """
- pass
-
-class DoneEchoERR(object):
- """
- Call back interface for 'echoERR' command.
- """
- def doneEchoERR(self, token, error, error_obj, error_msg):
- """
- Called when 'echoERR' command is done.
- @param token - command handle.
- @param error - communication error report or None.
- @param error_obj - error object, should be equal to the command argument.
- @param error_msg - error object converted to a human readable string.
- """
- pass
-
-class DoneGetTestList(object):
- """
- Call back interface for 'getTestList' command.
- """
- def doneGetTestList(self, token, error, list):
- """
- Called when 'getTestList' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param list - names of tests that are supported by the peer.
- """
- pass
-
-class DoneRunTest(object):
- """
- Call back interface for 'runTest' command.
- """
- def doneRunTest(self, token, error, context_id):
- """
- Called when 'runTest' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param context_id - test execution contest ID.
- """
- pass
-
-class DoneCancelTest(object):
- """
- Call back interface for 'cancelTest' command.
- """
- def doneCancelTest(self, token, error):
- """
- Called when 'cancelTest' command is done.
- @param token - command handle.
- @param error - error object or None.
- """
- pass
-
-class DoneGetSymbol(object):
- """
- Call back interface for 'getSymbol' command.
- """
- def doneGetSymbol(self, token, error, symbol):
- """
- Called when 'getSymbol' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param symbol
- """
- pass
-
-class Symbol(object):
- """
- Represents result value of 'getSymbol' command.
- """
- def __init__(self, props):
- self._props = props or {}
- def getSectionName(self):
- return self._props.get("Section")
- def getValue(self):
- return self._props.get("Value")
- def isUndef(self):
- val = self._props.get("Storage")
- return val == "UNDEF"
- def isCommon(self):
- val = self._props.get("Storage")
- return val == "COMMON"
- def isGlobal(self):
- val = self._props.get("Storage")
- return val == "GLOBAL"
- def isLocal(self):
- val = self._props.get("Storage")
- return val == "LOCAL"
- def isAbs(self):
- return self._props.get("Abs", False)
-
-class DoneCreateTestStreams(object):
- """
- Call back interface for 'createTestStreams' command.
- """
- def doneCreateTestStreams(self, token, error, inp_id, out_id):
- """
- Called when 'createTestStreams' command is done.
- @param token - command handle.
- @param error - error object or None.
- @param inp_id - the input stream ID.
- @param out_id - the output stream ID.
- """
- pass
-
-class DoneDisposeTestStream(object):
- """
- Call back interface for 'disposeTestStream' command.
- """
- def doneDisposeTestStream(self, token, error):
- """
- Called when 'createTestStreams' command is done.
- @param token - command handle.
- @param error - error object or None.
- """
- pass
-
-class DoneNotImplementedCommand(object):
- def doneNotImplementedCommand(self, token, error):
- """
- Called when 'not_implemented_command' command is done.
- @param token - command handle.
- @param error - error object.
- """
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+This is an optional service that can be implemented by a peer.
+If implemented, the service can be used for testing of the peer and
+communication channel functionality and reliability.
+"""
+
+from tcf import services
+
+NAME = "Diagnostics"
+
+class DiagnosticsService(services.Service):
+ def getName(self):
+ return NAME
+
+ def echo(self, s, done):
+ """
+ 'echo' command result returns same string that was given as command argument.
+ The command is used to test communication channel ability to transmit arbitrary strings in
+ both directions.
+ @param s - any string.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def echoFP(self, n, done):
+ """
+ 'echoFP' command result returns same floating point number that was given as command argument.
+ The command is used to test communication channel ability to transmit arbitrary floating point numbers in
+ both directions.
+ @param n - any floating point number.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def echoERR(self, error, done):
+ """
+ 'echoERR' command result returns same error report that was given as command argument.
+ The command is used to test remote agent ability to receive and transmit TCF error reports.
+ @param error - an error object.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def getTestList(self, done):
+ """
+ Get list of test names that are implemented by the service.
+ Clients can request remote peer to run a test from the list.
+ When started, a test performs a predefined set actions.
+ Nature of test actions is uniquely identified by test name.
+ Exact description of test actions is a contract between client and remote peer,
+ and it is not part of Diagnostics service specifications.
+ Clients should not attempt to run a test if they don't recognize the test name.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def runTest(self, name, done):
+ """
+ Run a test. When started, a test performs a predefined set actions.
+ Nature of test actions is uniquely identified by test name.
+ Running test usually has associated execution context ID.
+ Depending on the test, the ID can be used with services RunControl and/or Processes services to control
+ test execution, and to obtain test results.
+ @param name - test name
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def cancelTest(self, context_id, done):
+ """
+ Cancel execution of a test.
+ @param context_id - text execution context ID.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def getSymbol(self, context_id, symbol_name, done):
+ """
+ Get information about a symbol in text execution context.
+ @param context_id
+ @param symbol_name
+ @param done
+ @return
+ """
+ return NotImplementedError("Abstract method")
+
+ def createTestStreams(self, inp_buf_size, out_buf_size, done):
+ """
+ Create a pair of virtual streams, @see IStreams service.
+ Remote ends of the streams are connected, so any data sent into 'inp' stream
+ will become for available for reading from 'out' stream.
+ The command is used for testing virtual streams.
+ @param inp_buf_size - buffer size in bytes of the input stream.
+ @param out_buf_size - buffer size in bytes of the output stream.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def disposeTestStream(self, id, done):
+ """
+ Dispose a virtual stream that was created by 'createTestStreams' command.
+ @param id - the stream ID.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def not_implemented_command(self, done):
+ """
+ Send a command that is not implemented by peer.
+ Used to test handling of 'N' messages by communication channel.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+
+class DoneEcho(object):
+ """
+ Call back interface for 'echo' command.
+ """
+ def doneEcho(self, token, error, s):
+ """
+ Called when 'echo' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param s - same string as the command argument.
+ """
+ pass
+
+class DoneEchoFP(object):
+ """
+ Call back interface for 'echoFP' command.
+ """
+ def doneEchoFP(self, token, error, n):
+ """
+ Called when 'echoFP' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param n - same number as the command argument.
+ """
+ pass
+
+class DoneEchoERR(object):
+ """
+ Call back interface for 'echoERR' command.
+ """
+ def doneEchoERR(self, token, error, error_obj, error_msg):
+ """
+ Called when 'echoERR' command is done.
+ @param token - command handle.
+ @param error - communication error report or None.
+ @param error_obj - error object, should be equal to the command argument.
+ @param error_msg - error object converted to a human readable string.
+ """
+ pass
+
+class DoneGetTestList(object):
+ """
+ Call back interface for 'getTestList' command.
+ """
+ def doneGetTestList(self, token, error, list):
+ """
+ Called when 'getTestList' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param list - names of tests that are supported by the peer.
+ """
+ pass
+
+class DoneRunTest(object):
+ """
+ Call back interface for 'runTest' command.
+ """
+ def doneRunTest(self, token, error, context_id):
+ """
+ Called when 'runTest' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param context_id - test execution contest ID.
+ """
+ pass
+
+class DoneCancelTest(object):
+ """
+ Call back interface for 'cancelTest' command.
+ """
+ def doneCancelTest(self, token, error):
+ """
+ Called when 'cancelTest' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ """
+ pass
+
+class DoneGetSymbol(object):
+ """
+ Call back interface for 'getSymbol' command.
+ """
+ def doneGetSymbol(self, token, error, symbol):
+ """
+ Called when 'getSymbol' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param symbol
+ """
+ pass
+
+class Symbol(object):
+ """
+ Represents result value of 'getSymbol' command.
+ """
+ def __init__(self, props):
+ self._props = props or {}
+ def getSectionName(self):
+ return self._props.get("Section")
+ def getValue(self):
+ return self._props.get("Value")
+ def isUndef(self):
+ val = self._props.get("Storage")
+ return val == "UNDEF"
+ def isCommon(self):
+ val = self._props.get("Storage")
+ return val == "COMMON"
+ def isGlobal(self):
+ val = self._props.get("Storage")
+ return val == "GLOBAL"
+ def isLocal(self):
+ val = self._props.get("Storage")
+ return val == "LOCAL"
+ def isAbs(self):
+ return self._props.get("Abs", False)
+
+class DoneCreateTestStreams(object):
+ """
+ Call back interface for 'createTestStreams' command.
+ """
+ def doneCreateTestStreams(self, token, error, inp_id, out_id):
+ """
+ Called when 'createTestStreams' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param inp_id - the input stream ID.
+ @param out_id - the output stream ID.
+ """
+ pass
+
+class DoneDisposeTestStream(object):
+ """
+ Call back interface for 'disposeTestStream' command.
+ """
+ def doneDisposeTestStream(self, token, error):
+ """
+ Called when 'createTestStreams' command is done.
+ @param token - command handle.
+ @param error - error object or None.
+ """
+ pass
+
+class DoneNotImplementedCommand(object):
+ def doneNotImplementedCommand(self, token, error):
+ """
+ Called when 'not_implemented_command' command is done.
+ @param token - command handle.
+ @param error - error object.
+ """
+ pass
diff --git a/python/src/tcf/services/disassembly.py b/python/src/tcf/services/disassembly.py
index 18abad1ae..f5260c3b5 100644
--- a/python/src/tcf/services/disassembly.py
+++ b/python/src/tcf/services/disassembly.py
@@ -1,131 +1,131 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-TCF Disassembly service interface.
-"""
-
-from tcf import services
-
-NAME = "Disassembly"
-
-# The name of the instruction set architecture, String
-CAPABILITY_ISA = "ISA"
-
-# If true, simplified mnemonics are supported or requested, Boolean
-CAPABILITY_SIMPLIFIED = "Simplified"
-
-# If true, pseudo-instructions are supported or requested, Boolean
-CAPABILITY_PSEUDO = "Pseudo"
-
-
-# Instruction field properties
-# The type of the instruction field. See FTYPE_*, String.
-FIELD_TYPE = "Type"
-
-# Value of the field for "String" and "Register" types, String.
-FIELD_TEXT = "Text"
-
-# Value of the field for "Address," "Displacement," or "Immediate" types, Number.
-FIELD_VALUE = "Value"
-
-# Context ID of the address space used with "Address" types, String.
-FIELD_ADDRESS_SPACE = "AddressSpace"
-
-# Instruction field types
-FTYPE_STRING = "String"
-FTYPE_Register = "Register"
-FTYPE_ADDRESS = "Address"
-FTYPE_DISPLACEMENT = "Displacement"
-FTYPE_IMMEDIATE = "Immediate"
-
-
-class DisassemblyService(services.Service):
- def getName(self):
- return NAME
-
- def getCapabilities(self, context_id, done):
- """
- Retrieve disassembly service capabilities a given context-id.
- @param context_id - a context ID, usually one returned by Run Control or Memory services.
- @param done - command result call back object.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def disassemble(self, context_id, addr, size, params, done):
- """
- Disassemble instruction code from a specified range of memory addresses, in a specified context.
- @param context_id - a context ID, usually one returned by Run Control or Memory services.
- @param addr - address of first instruction to disassemble.
- @param size - size in bytes of the address range.
- @param params - properties to control the disassembly output, an element of capabilities array, see getCapabilities.
- @param done - command result call back object.
- @return - pending command handle.
- """
-
-
-class DoneGetCapabilities(object):
- """
- Call back interface for 'getCapabilities' command.
- """
- def doneGetCapabilities(self, token, error, capabilities):
- """
- Called when capabilities retrieval is done.
- @param token - command handle.
- @param error - error object or None.
- @param capabilities - array of capabilities, see CAPABILITY_* for contents of each array element.
- """
- pass
-
-class DoneDisassemble(object):
- """
- Call back interface for 'disassemble' command.
- """
- def doneDisassemble(self, token, error, disassembly):
- """
- Called when disassembling is done.
- @param token - command handle.
- @param error - error object or None.
- @param disassembly - array of disassembly lines.
- """
- pass
-
-class DisassemblyLine(object):
- """
- Represents a single disassembly line.
- """
- def __init__(self, addr, size, instruction):
- self.addr = addr
- self.size = size or 0
- self.instruction = instruction
-
- def getAddress(self):
- """
- @return instruction address.
- """
- return self.addr
-
- def getSize(self):
- """
- @return instruction size in bytes.
- """
- return self.size
-
- def getInstruction(self):
- """
- @return array of instruction fields, each field is a collection of field properties, see FIELD_*.
- """
- return self.instruction
-
- def __str__(self):
- instr = "".join(map(str, self.instruction))
- return "[%s %s %s]" % (self.addr, self.size, instr)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+TCF Disassembly service interface.
+"""
+
+from tcf import services
+
+NAME = "Disassembly"
+
+# The name of the instruction set architecture, String
+CAPABILITY_ISA = "ISA"
+
+# If true, simplified mnemonics are supported or requested, Boolean
+CAPABILITY_SIMPLIFIED = "Simplified"
+
+# If true, pseudo-instructions are supported or requested, Boolean
+CAPABILITY_PSEUDO = "Pseudo"
+
+
+# Instruction field properties
+# The type of the instruction field. See FTYPE_*, String.
+FIELD_TYPE = "Type"
+
+# Value of the field for "String" and "Register" types, String.
+FIELD_TEXT = "Text"
+
+# Value of the field for "Address," "Displacement," or "Immediate" types, Number.
+FIELD_VALUE = "Value"
+
+# Context ID of the address space used with "Address" types, String.
+FIELD_ADDRESS_SPACE = "AddressSpace"
+
+# Instruction field types
+FTYPE_STRING = "String"
+FTYPE_Register = "Register"
+FTYPE_ADDRESS = "Address"
+FTYPE_DISPLACEMENT = "Displacement"
+FTYPE_IMMEDIATE = "Immediate"
+
+
+class DisassemblyService(services.Service):
+ def getName(self):
+ return NAME
+
+ def getCapabilities(self, context_id, done):
+ """
+ Retrieve disassembly service capabilities a given context-id.
+ @param context_id - a context ID, usually one returned by Run Control or Memory services.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def disassemble(self, context_id, addr, size, params, done):
+ """
+ Disassemble instruction code from a specified range of memory addresses, in a specified context.
+ @param context_id - a context ID, usually one returned by Run Control or Memory services.
+ @param addr - address of first instruction to disassemble.
+ @param size - size in bytes of the address range.
+ @param params - properties to control the disassembly output, an element of capabilities array, see getCapabilities.
+ @param done - command result call back object.
+ @return - pending command handle.
+ """
+
+
+class DoneGetCapabilities(object):
+ """
+ Call back interface for 'getCapabilities' command.
+ """
+ def doneGetCapabilities(self, token, error, capabilities):
+ """
+ Called when capabilities retrieval is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param capabilities - array of capabilities, see CAPABILITY_* for contents of each array element.
+ """
+ pass
+
+class DoneDisassemble(object):
+ """
+ Call back interface for 'disassemble' command.
+ """
+ def doneDisassemble(self, token, error, disassembly):
+ """
+ Called when disassembling is done.
+ @param token - command handle.
+ @param error - error object or None.
+ @param disassembly - array of disassembly lines.
+ """
+ pass
+
+class DisassemblyLine(object):
+ """
+ Represents a single disassembly line.
+ """
+ def __init__(self, addr, size, instruction):
+ self.addr = addr
+ self.size = size or 0
+ self.instruction = instruction
+
+ def getAddress(self):
+ """
+ @return instruction address.
+ """
+ return self.addr
+
+ def getSize(self):
+ """
+ @return instruction size in bytes.
+ """
+ return self.size
+
+ def getInstruction(self):
+ """
+ @return array of instruction fields, each field is a collection of field properties, see FIELD_*.
+ """
+ return self.instruction
+
+ def __str__(self):
+ instr = "".join(map(str, self.instruction))
+ return "[%s %s %s]" % (self.addr, self.size, instr)
diff --git a/python/src/tcf/services/expressions.py b/python/src/tcf/services/expressions.py
index 8da3b61e6..5b32a1c30 100644
--- a/python/src/tcf/services/expressions.py
+++ b/python/src/tcf/services/expressions.py
@@ -1,356 +1,356 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Expressions service allows TCF client to perform expression evaluation on remote target.
-The service can be used to retrieve or modify values of variables or any data structures in remote target memory.
-"""
-
-from tcf import services
-
-# Service name.
-NAME = "Expressions"
-
-class Expression(object):
- """
- Expression object represent an expression that can be evaluated by remote target.
- It has a unique ID and contains all information necessary to compute a value.
- The object data usually includes:
- 1. process, thread or stack frame ID that should be used to resolve symbol names
- 2. a script that can compute a value, like "x.y + z"
- """
- def __init__(self, props):
- self._props = props or {}
-
- def __str__(self):
- return "[Expression Context %s]" % self._props
-
- def getID(self):
- """
- Get context ID.
- @return context ID.
- """
- return self._props.get(PROP_ID)
-
- def getParentID(self):
- """
- Get parent context ID.
- @return parent context ID.
- """
- return self._props.get(PROP_PARENT_ID)
-
- def getLanguage(self):
- """
- Get expression script language ID.
- @return language ID.
- """
- return self._props.get(PROP_LANGUAGE)
-
- def getExpression(self):
- """
- Return expression string - the script part of the context.
- @return expression script string
- """
- return self._props.get(PROP_EXPRESSION)
-
- def getSymbolID(self):
- """
- Return symbol ID if the expression represents a symbol (e.g. local variable).
- @return symbol ID
- """
- return self._props.get(PROP_SYMBOL_ID)
-
- def getBits(self):
- """
- Get size of expression value in bits.
- Can be 0 if value size is even number of bytes, use getSize() in such case.
- @return size in bits.
- """
- return self._props.get(PROP_BITS, 0)
-
- def getSize(self):
- """
- Get size in bytes. The size can include extra (unused) bits.
- This is "static" or "declared" size - as determined by expression type.
- @return size in bytes.
- """
- return self._props.get(PROP_SIZE, 0)
-
- def getTypeID(self):
- """
- Get expression type ID. Symbols service can be used to get type properties.
- This is "static" or "declared" type ID, actual type of a value can be different -
- if expression language supports dynamic typing.
- @return type ID.
- """
- return self._props.get(PROP_TYPE)
-
- def canAssign(self):
- """
- Check if the expression can be assigned a new value.
- @return true if can assign.
- """
- return self._props.get(PROP_CAN_ASSIGN)
-
- def getProperties(self):
- """
- Get complete map of context properties.
- @return map of context properties.
- """
- return self._props
-
-# Expression context property names.
-PROP_ID = "ID"
-PROP_PARENT_ID = "ParentID"
-PROP_SYMBOL_ID = "SymbolID"
-PROP_LANGUAGE = "Language"
-PROP_EXPRESSION = "Expression"
-PROP_BITS = "Bits"
-PROP_SIZE = "Size"
-PROP_TYPE = "Type"
-PROP_CAN_ASSIGN = "CanAssign"
-
-class Value(object):
- """
- Value represents result of expression evaluation.
- Note that same expression can be evaluated multiple times with different results.
- """
- def __init__(self, value, props):
- self._value = value
- self._props = props or {}
-
- def __str__(self):
- return "[Expression Value %s %s]" % (self._value, self._props)
-
- def getTypeClass(self):
- """
- Get value type class.
- @see symbols.TypeClass
- @return type class
- """
- return self._props.get(VAL_CLASS, 0)
-
- def getTypeID(self):
- """
- Get value type ID. Symbols service can be used to get type properties.
- @return type ID.
- """
- return self._props.get(VAL_TYPE)
-
- def isBigEndian(self):
- """
- Check endianness of the values.
- Big-endian means decreasing numeric significance with increasing byte number.
- @return true if big-endian.
- """
- return self._props.get(VAL_BIG_ENDIAN)
-
- def getValue(self):
- """
- Get value as array of bytes.
- @return value as array of bytes.
- """
- return self._value
-
- def getProperties(self):
- """
- Get complete map of value properties.
- @return map of value properties.
- """
- return self._props
-
-# Expression value property names.
-VAL_CLASS = "Class"
-VAL_TYPE = "Type"
-VAL_BIG_ENDIAN = "BigEndian"
-
-class ExpressionsService(services.Service):
- def getName(self):
- return NAME
-
- def getContext(self, id, done):
- """
- Retrieve expression context info for given context ID.
- @see Expression
-
- @param id - context ID.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def getChildren(self, parent_context_id, done):
- """
- Retrieve children IDs for given parent ID.
- Meaning of the operation depends on parent kind:
- 1. expression with type of a struct, union, or class - fields
- 2. expression with type of an enumeration - enumerators
- 3. expression with type of an array - array elements
- 4. stack frame - function arguments and local variables
- 5. thread - top stack frame function arguments and local variables
- 6. process - global variables
-
- Children list *does not* include IDs of expressions that were created by clients
- using "create" command.
-
- @param parent_context_id - parent context ID.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def create(self, parent_id, language, expression, done):
- """
- Create an expression context.
- The context should be disposed after use.
- @param parent_id - a context ID that can be used to resolve symbol names.
- @param language - language of expression script, None means default language
- @param expression - expression script
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def dispose(self, id, done):
- """
- Dispose an expression context that was created by create()
- @param id - the expression context ID
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def evaluate(self, id, done):
- """
- Evaluate value of an expression context.
- @param id - the expression context ID
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def assign(self, id, value, done):
- """
- Assign a value to memory location determined by an expression.
- @param id - expression ID.
- @param value - value as an array of bytes.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def addListener(self, listener):
- """
- Add expressions service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
- def removeListener(self, listener):
- """
- Remove expressions service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
-class DoneGetContext(object):
- """
- Client call back interface for getContext().
- """
- def doneGetContext(self, token, error, context):
- """
- Called when context data retrieval is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- @param context - context properties.
- """
- pass
-
-class DoneGetChildren(object):
- """
- Client call back interface for getChildren().
- """
- def doneGetChildren(self, token, error, context_ids):
- """
- Called when context list retrieval is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- @param context_ids - array of available context IDs.
- """
- pass
-
-
-class DoneCreate(object):
- """
- Client call back interface for create().
- """
- def doneCreate(self, token, error, context):
- """
- Called when context create context command is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- @param context - context properties.
- """
- pass
-
-class DoneDispose(object):
- """
- Client call back interface for dispose().
- """
- def doneDispose(self, token, error):
- """
- Called when context dispose command is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- """
- pass
-
-class DoneEvaluate(object):
- """
- Client call back interface for evaluate().
- """
- def doneEvaluate(self, token, error, value):
- """
- Called when context dispose command is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- @param value - expression evaluation result
- """
- pass
-
-class DoneAssign(object):
- """
- Client call back interface for assign().
- """
- def doneAssign(self, token, error):
- """
- Called when assign command is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- """
- pass
-
-class ExpressionsListener(object):
- """
- Registers event listener is notified when registers context hierarchy
- changes, and when a register is modified by the service commands.
- """
- def valueChanged(self, id):
- """
- Called when expression value was changed and clients
- need to update themselves. Clients, at least, should invalidate
- corresponding cached expression data.
- Not every change is notified - it is not possible,
- only those, which are not caused by normal execution of the debuggee.
- At least, changes caused by "assign" command should be notified.
- @param id - expression context ID.
- """
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Expressions service allows TCF client to perform expression evaluation on remote target.
+The service can be used to retrieve or modify values of variables or any data structures in remote target memory.
+"""
+
+from tcf import services
+
+# Service name.
+NAME = "Expressions"
+
+class Expression(object):
+ """
+ Expression object represent an expression that can be evaluated by remote target.
+ It has a unique ID and contains all information necessary to compute a value.
+ The object data usually includes:
+ 1. process, thread or stack frame ID that should be used to resolve symbol names
+ 2. a script that can compute a value, like "x.y + z"
+ """
+ def __init__(self, props):
+ self._props = props or {}
+
+ def __str__(self):
+ return "[Expression Context %s]" % self._props
+
+ def getID(self):
+ """
+ Get context ID.
+ @return context ID.
+ """
+ return self._props.get(PROP_ID)
+
+ def getParentID(self):
+ """
+ Get parent context ID.
+ @return parent context ID.
+ """
+ return self._props.get(PROP_PARENT_ID)
+
+ def getLanguage(self):
+ """
+ Get expression script language ID.
+ @return language ID.
+ """
+ return self._props.get(PROP_LANGUAGE)
+
+ def getExpression(self):
+ """
+ Return expression string - the script part of the context.
+ @return expression script string
+ """
+ return self._props.get(PROP_EXPRESSION)
+
+ def getSymbolID(self):
+ """
+ Return symbol ID if the expression represents a symbol (e.g. local variable).
+ @return symbol ID
+ """
+ return self._props.get(PROP_SYMBOL_ID)
+
+ def getBits(self):
+ """
+ Get size of expression value in bits.
+ Can be 0 if value size is even number of bytes, use getSize() in such case.
+ @return size in bits.
+ """
+ return self._props.get(PROP_BITS, 0)
+
+ def getSize(self):
+ """
+ Get size in bytes. The size can include extra (unused) bits.
+ This is "static" or "declared" size - as determined by expression type.
+ @return size in bytes.
+ """
+ return self._props.get(PROP_SIZE, 0)
+
+ def getTypeID(self):
+ """
+ Get expression type ID. Symbols service can be used to get type properties.
+ This is "static" or "declared" type ID, actual type of a value can be different -
+ if expression language supports dynamic typing.
+ @return type ID.
+ """
+ return self._props.get(PROP_TYPE)
+
+ def canAssign(self):
+ """
+ Check if the expression can be assigned a new value.
+ @return true if can assign.
+ """
+ return self._props.get(PROP_CAN_ASSIGN)
+
+ def getProperties(self):
+ """
+ Get complete map of context properties.
+ @return map of context properties.
+ """
+ return self._props
+
+# Expression context property names.
+PROP_ID = "ID"
+PROP_PARENT_ID = "ParentID"
+PROP_SYMBOL_ID = "SymbolID"
+PROP_LANGUAGE = "Language"
+PROP_EXPRESSION = "Expression"
+PROP_BITS = "Bits"
+PROP_SIZE = "Size"
+PROP_TYPE = "Type"
+PROP_CAN_ASSIGN = "CanAssign"
+
+class Value(object):
+ """
+ Value represents result of expression evaluation.
+ Note that same expression can be evaluated multiple times with different results.
+ """
+ def __init__(self, value, props):
+ self._value = value
+ self._props = props or {}
+
+ def __str__(self):
+ return "[Expression Value %s %s]" % (self._value, self._props)
+
+ def getTypeClass(self):
+ """
+ Get value type class.
+ @see symbols.TypeClass
+ @return type class
+ """
+ return self._props.get(VAL_CLASS, 0)
+
+ def getTypeID(self):
+ """
+ Get value type ID. Symbols service can be used to get type properties.
+ @return type ID.
+ """
+ return self._props.get(VAL_TYPE)
+
+ def isBigEndian(self):
+ """
+ Check endianness of the values.
+ Big-endian means decreasing numeric significance with increasing byte number.
+ @return true if big-endian.
+ """
+ return self._props.get(VAL_BIG_ENDIAN)
+
+ def getValue(self):
+ """
+ Get value as array of bytes.
+ @return value as array of bytes.
+ """
+ return self._value
+
+ def getProperties(self):
+ """
+ Get complete map of value properties.
+ @return map of value properties.
+ """
+ return self._props
+
+# Expression value property names.
+VAL_CLASS = "Class"
+VAL_TYPE = "Type"
+VAL_BIG_ENDIAN = "BigEndian"
+
+class ExpressionsService(services.Service):
+ def getName(self):
+ return NAME
+
+ def getContext(self, id, done):
+ """
+ Retrieve expression context info for given context ID.
+ @see Expression
+
+ @param id - context ID.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getChildren(self, parent_context_id, done):
+ """
+ Retrieve children IDs for given parent ID.
+ Meaning of the operation depends on parent kind:
+ 1. expression with type of a struct, union, or class - fields
+ 2. expression with type of an enumeration - enumerators
+ 3. expression with type of an array - array elements
+ 4. stack frame - function arguments and local variables
+ 5. thread - top stack frame function arguments and local variables
+ 6. process - global variables
+
+ Children list *does not* include IDs of expressions that were created by clients
+ using "create" command.
+
+ @param parent_context_id - parent context ID.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def create(self, parent_id, language, expression, done):
+ """
+ Create an expression context.
+ The context should be disposed after use.
+ @param parent_id - a context ID that can be used to resolve symbol names.
+ @param language - language of expression script, None means default language
+ @param expression - expression script
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def dispose(self, id, done):
+ """
+ Dispose an expression context that was created by create()
+ @param id - the expression context ID
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def evaluate(self, id, done):
+ """
+ Evaluate value of an expression context.
+ @param id - the expression context ID
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def assign(self, id, value, done):
+ """
+ Assign a value to memory location determined by an expression.
+ @param id - expression ID.
+ @param value - value as an array of bytes.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def addListener(self, listener):
+ """
+ Add expressions service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def removeListener(self, listener):
+ """
+ Remove expressions service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+class DoneGetContext(object):
+ """
+ Client call back interface for getContext().
+ """
+ def doneGetContext(self, token, error, context):
+ """
+ Called when context data retrieval is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ @param context - context properties.
+ """
+ pass
+
+class DoneGetChildren(object):
+ """
+ Client call back interface for getChildren().
+ """
+ def doneGetChildren(self, token, error, context_ids):
+ """
+ Called when context list retrieval is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ @param context_ids - array of available context IDs.
+ """
+ pass
+
+
+class DoneCreate(object):
+ """
+ Client call back interface for create().
+ """
+ def doneCreate(self, token, error, context):
+ """
+ Called when context create context command is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ @param context - context properties.
+ """
+ pass
+
+class DoneDispose(object):
+ """
+ Client call back interface for dispose().
+ """
+ def doneDispose(self, token, error):
+ """
+ Called when context dispose command is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ """
+ pass
+
+class DoneEvaluate(object):
+ """
+ Client call back interface for evaluate().
+ """
+ def doneEvaluate(self, token, error, value):
+ """
+ Called when context dispose command is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ @param value - expression evaluation result
+ """
+ pass
+
+class DoneAssign(object):
+ """
+ Client call back interface for assign().
+ """
+ def doneAssign(self, token, error):
+ """
+ Called when assign command is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ """
+ pass
+
+class ExpressionsListener(object):
+ """
+ Registers event listener is notified when registers context hierarchy
+ changes, and when a register is modified by the service commands.
+ """
+ def valueChanged(self, id):
+ """
+ Called when expression value was changed and clients
+ need to update themselves. Clients, at least, should invalidate
+ corresponding cached expression data.
+ Not every change is notified - it is not possible,
+ only those, which are not caused by normal execution of the debuggee.
+ At least, changes caused by "assign" command should be notified.
+ @param id - expression context ID.
+ """
+ pass
diff --git a/python/src/tcf/services/filesystem.py b/python/src/tcf/services/filesystem.py
index 524bea907..726b71810 100644
--- a/python/src/tcf/services/filesystem.py
+++ b/python/src/tcf/services/filesystem.py
@@ -1,603 +1,603 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-File System service provides file transfer (and more generally file
-system access) functionality in TCF. The service design is
-derived from SSH File Transfer Protocol specifications.
-
- Request Synchronization and Reordering
-
-The protocol and implementations MUST process requests relating to
-the same file in the order in which they are received. In other
-words, if an application submits multiple requests to the server, the
-results in the responses will be the same as if it had sent the
-requests one at a time and waited for the response in each case. For
-example, the server may process non-overlapping read/write requests
-to the same file in parallel, but overlapping reads and writes cannot
-be reordered or parallelized. However, there are no ordering
-restrictions on the server for processing requests from two different
-file transfer connections. The server may interleave and parallelize
-them at will.
-
-There are no restrictions on the order in which responses to
-outstanding requests are delivered to the client, except that the
-server must ensure fairness in the sense that processing of no
-request will be indefinitely delayed even if the client is sending
-other requests so that there are multiple outstanding requests all
-the time.
-
-There is no limit on the number of outstanding (non-acknowledged)
-requests that the client may send to the server. In practice this is
-limited by the buffering available on the data stream and the queuing
-performed by the server. If the server's queues are full, it should
-not read any more data from the stream, and flow control will prevent
-the client from sending more requests.
-
- File Names
-
-This protocol represents file names as strings. File names are
-assumed to use the slash ('/') character as a directory separator.
-
-File names starting with a slash are "absolute", and are relative to
-the root of the file system. Names starting with any other character
-are relative to the user's default directory (home directory). Client
-can use 'user()' command to retrieve current user home directory.
-
-Servers SHOULD interpret a path name component ".." as referring to
-the parent directory, and "." as referring to the current directory.
-If the server implementation limits access to certain parts of the
-file system, it must be extra careful in parsing file names when
-enforcing such restrictions. There have been numerous reported
-security bugs where a ".." in a path name has allowed access outside
-the intended area.
-
-An empty path name is valid, and it refers to the user's default
-directory (usually the user's home directory).
-
-Otherwise, no syntax is defined for file names by this specification.
-Clients should not make any other assumptions however, they can
-splice path name components returned by readdir() together
-using a slash ('/') as the separator, and that will work as expected.
-"""
-
-from tcf import services
-
-# Service name.
-NAME = "FileSystem"
-
-# Flags to be used with open() method.
-
-# Open the file for reading.
-TCF_O_READ = 0x00000001
-
-# Open the file for writing. If both this and TCF_O_READ are
-# specified, the file is opened for both reading and writing.
-TCF_O_WRITE = 0x00000002
-
-# Force all writes to append data at the end of the file.
-TCF_O_APPEND = 0x00000004
-
-# If this flag is specified, then a new file will be created if one
-# does not already exist (if TCF_O_TRUNC is specified, the new file will
-# be truncated to zero length if it previously exists).
-TCF_O_CREAT = 0x00000008
-
-# Forces an existing file with the same name to be truncated to zero
-# length when creating a file by specifying TCF_O_CREAT.
-# TCF_O_CREAT MUST also be specified if this flag is used.
-TCF_O_TRUNC = 0x00000010
-
-# Causes the request to fail if the named file already exists.
-# TCF_O_CREAT MUST also be specified if this flag is used.
-TCF_O_EXCL = 0x00000020
-
-# Flags to be used together with FileAttrs.
-# The flags specify which of the fields are present. Those fields
-# for which the corresponding flag is not set are not present (not
-# included in the message).
-ATTR_SIZE = 0x00000001
-ATTR_UIDGID = 0x00000002
-ATTR_PERMISSIONS = 0x00000004
-ATTR_ACMODTIME = 0x00000008
-
-class FileAttrs(object):
- """
- FileAttrs is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- Fields:
- The 'flags' specify which of the fields are present.
- The 'size' field specifies the size of the file in bytes.
- The 'uid' and 'gid' fields contain numeric Unix-like user and group
- identifiers, respectively.
- The 'permissions' field contains a bit mask of file permissions as
- defined by posix [1].
- The 'atime' and 'mtime' contain the access and modification times of
- the files, respectively. They are represented as milliseconds from
- midnight Jan 1, 1970 in UTC.
- attributes - Additional (non-standard) attributes.
- """
- def __init__(self, flags, size, uid, gid, permissions, atime, mtime, attributes):
- self.flags = flags
- self.size = size
- self.uid = uid
- self.gid = gid
- self.permissions = permissions
- self.atime = atime
- self.mtime = mtime
- self.attributes = attributes
-
- def isFile(self):
- """
- Determines if the file system object is a file on the remote file system.
-
- @return True if and only if the object on the remote system can be considered to have "contents" that
- have the potential to be read and written as a byte stream.
- """
- if (self.flags & ATTR_PERMISSIONS) == 0: return False
- return (self.permissions & S_IFMT) == S_IFREG
-
- def isDirectory(self):
- """
- Determines if the file system object is a directory on the remote file system.
-
- @return True if and only if the object on the remote system is a directory.
- That is, it contains entries that can be interpreted as other files.
- """
- if (self.flags & ATTR_PERMISSIONS) == 0: return False
- return (self.permissions & S_IFMT) == S_IFDIR
-
-# The following flags are defined for the 'permissions' field:
-S_IFMT = 0170000 # bitmask for the file type bitfields
-S_IFSOCK = 0140000 # socket
-S_IFLNK = 0120000 # symbolic link
-S_IFREG = 0100000 # regular file
-S_IFBLK = 0060000 # block device
-S_IFDIR = 0040000 # directory
-S_IFCHR = 0020000 # character device
-S_IFIFO = 0010000 # fifo
-S_ISUID = 0004000 # set UID bit
-S_ISGID = 0002000 # set GID bit (see below)
-S_ISVTX = 0001000 # sticky bit (see below)
-S_IRWXU = 00700 # mask for file owner permissions
-S_IRUSR = 00400 # owner has read permission
-S_IWUSR = 00200 # owner has write permission
-S_IXUSR = 00100 # owner has execute permission
-S_IRWXG = 00070 # mask for group permissions
-S_IRGRP = 00040 # group has read permission
-S_IWGRP = 00020 # group has write permission
-S_IXGRP = 00010 # group has execute permission
-S_IRWXO = 00007 # mask for permissions for others (not in group)
-S_IROTH = 00004 # others have read permission
-S_IWOTH = 00002 # others have write permission
-S_IXOTH = 00001 # others have execute permission
-
-class DirEntry(object):
- """
- Directory entry.
- Fields:
- 'filename' is a file name being returned. It is a relative name within
- the directory, without any path components
- 'longname' is an expanded format for the file name, similar to what
- is returned by "ls -l" on Unix systems.
- The format of the 'longname' field is unspecified by this protocol.
- It MUST be suitable for use in the output of a directory listing
- command (in fact, the recommended operation for a directory listing
- command is to simply display this data). However, clients SHOULD NOT
- attempt to parse the longname field for file attributes they SHOULD
- use the attrs field instead.
- 'attrs' is the attributes of the file.
- """
- def __init__(self, filename, longname, attrs):
- self.filename = filename
- self.longname = longname
- self.attrs = attrs
-
-class FileHandle(object):
- def __init__(self, service, id):
- self.service = service
- self.id = id
-
- def getService(self):
- return self.service
-
- def __str__(self):
- return "[File Handle '%s'" % self.id
-
-# Service specific error codes.
-
-# Indicates end-of-file condition for read() it means that no
-# more data is available in the file, and for readdir() it
-# indicates that no more files are contained in the directory.
-STATUS_EOF = 0x10001
-
-# This code is returned when a reference is made to a file which
-# should exist but doesn't.
-STATUS_NO_SUCH_FILE = 0x10002
-
-# is returned when the authenticated user does not have sufficient
-# permissions to perform the operation.
-STATUS_PERMISSION_DENIED = 0x10003
-
-class FileSystemException(IOError):
- """
- The class to represent File System error reports.
- """
- def __init__(self, message_or_exception):
- if isinstance(message_or_exception, str):
- super(FileSystemException, self).__init__(message_or_exception)
- elif isinstance(message_or_exception, Exception):
- self.caused_by = message_or_exception
- def getStatus(self):
- """
- Get error code. The code can be standard TCF error code or
- one of service specific codes, see STATUS_*.
- @return error code.
- """
- raise NotImplementedError("Abstract methods")
-
-class FileSystemService(services.Service):
- def getName(self):
- return NAME
-
- def open(self, file_name, flags, attrs, done):
- """
- Open or create a file on a remote system.
-
- @param file_name specifies the file name. See 'File Names' for more information.
- @param flags is a bit mask of TCF_O_* flags.
- @param attrs specifies the initial attributes for the file.
- Default values will be used for those attributes that are not specified.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def close(self, handle, done):
- """
- Close a file on a remote system.
-
- @param handle is a handle previously returned in the response to
- open() or opendir().
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def read(self, handle, offset, len, done):
- """
- Read bytes from an open file.
- In response to this request, the server will read as many bytes as it
- can from the file (up to 'len'), and return them in a byte array.
- If an error occurs or EOF is encountered, the server may return
- fewer bytes then requested. Call back method doneRead() argument 'error'
- will be not None in case of error, and argument 'eof' will be
- True in case of EOF. For normal disk files, it is guaranteed
- that this will read the specified number of bytes, or up to end of file
- or error. For e.g. device files this may return fewer bytes than requested.
-
- @param handle is an open file handle returned by open().
- @param offset is the offset (in bytes) relative
- to the beginning of the file from where to start reading.
- If offset < 0 then reading starts from current position in the file.
- @param len is the maximum number of bytes to read.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def write(self, handle, offset, data, data_pos, data_size, done):
- """
- Write bytes into an open file.
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data.
-
- @param handle is an open file handle returned by open().
- @param offset is the offset (in bytes) relative
- to the beginning of the file from where to start writing.
- If offset < 0 then writing starts from current position in the file.
- @param data is byte array that contains data for writing.
- @param data_pos if offset in 'data' of first byte to write.
- @param data_size is the number of bytes to write.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def stat(self, path, done):
- """
- Retrieve file attributes.
-
- @param path - specifies the file system object for which
- status is to be returned.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def lstat(self, path, done):
- """
- Retrieve file attributes.
- Unlike 'stat()', 'lstat()' does not follow symbolic links.
-
- @param path - specifies the file system object for which
- status is to be returned.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def fstat(self, handle, done):
- """
- Retrieve file attributes for an open file (identified by the file handle).
-
- @param handle is a file handle returned by 'open()'.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def setstat(self, path, attrs, done):
- """
- Set file attributes.
- This request is used for operations such as changing the ownership,
- permissions or access times, as well as for truncating a file.
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes.
-
- @param path specifies the file system object (e.g. file or directory)
- whose attributes are to be modified.
- @param attrs specifies the modifications to be made to file attributes.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def fsetstat(self, handle, attrs, done):
- """
- Set file attributes for an open file (identified by the file handle).
- This request is used for operations such as changing the ownership,
- permissions or access times, as well as for truncating a file.
-
- @param handle is a file handle returned by 'open()'.
- @param attrs specifies the modifications to be made to file attributes.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def opendir(self, path, done):
- """
- The opendir() command opens a directory for reading.
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using readdir() requests.
- When the client no longer wishes to read more names from the
- directory, it SHOULD call close() for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
- @param path - name of the directory to be listed (without any trailing slash).
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def readdir(self, handle, done):
- """
- The files in a directory can be listed using the opendir() and
- readdir() requests. Each readdir() request returns one
- or more file names with full file attributes for each file. The
- client should call readdir() repeatedly until it has found the
- file it is looking for or until the server responds with a
- message indicating an error or end of file. The client should then
- close the handle using the close() request.
- Note: directory entries "." and ".." are NOT included into readdir()
- response.
- @param handle - file handle created by opendir()
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def mkdir(self, path, attrs, done):
- """
- Create a directory on the server.
-
- @param path - specifies the directory to be created.
- @param attrs - new directory attributes.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def rmdir(self, path, done):
- """
- Remove a directory.
- An error will be returned if no directory
- with the specified path exists, or if the specified directory is not
- empty, or if the path specified a file system object other than a
- directory.
-
- @param path - specifies the directory to be removed.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def roots(self, done):
- """
- Retrieve file system roots - top level file system objects.
- UNIX file system can report just one root with path "/". Other types of systems
- can have more the one root. For example, Windows server can return multiple roots:
- one per disc (e.g. "/C:/", "/D:/", etc.). Note: even Windows implementation of
- the service must use forward slash as directory separator, and must start
- absolute path with "/". Server should implement proper translation of
- protocol file names to OS native names and back.
-
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def remove(self, file_name, done):
- """
- Remove a file or symbolic link.
- This request cannot be used to remove directories.
-
- @param file_name is the name of the file to be removed.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def realpath(self, path, done):
- """
- Canonicalize any given path name to an absolute path.
- This is useful for converting path names containing ".." components or
- relative pathnames without a leading slash into absolute paths.
-
- @param path specifies the path name to be canonicalized.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def rename(self, old_path, new_path, done):
- """
- Rename a file.
- It is an error if there already exists a file
- with the name specified by 'new_path'. The server may also fail rename
- requests in other situations, for example if 'old_path' and 'new_path'
- point to different file systems on the server.
-
- @param old_path is the name of an existing file or directory.
- @param new_path is the new name for the file or directory.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def readlink(self, path, done):
- """
- Read the target of a symbolic link.
-
- @param path specifies the path name of the symbolic link to be read.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def symlink(self, link_path, target_path, done):
- """
- Create a symbolic link on the server.
-
- @param link_path specifies the path name of the symbolic link to be created.
- @param target_path specifies the target of the symbolic link.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def copy(self, src_path, dst_path, copy_permissions, copy_ownership, done):
- """
- Copy a file on remote system.
-
- @param src_path specifies the path name of the file to be copied.
- @param dst_path specifies destination file name.
- @param copy_permissions - if True then copy source file permissions.
- @param copy_ownership - if True then copy source file UID and GID.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def user(self, done):
- """
- Retrieve information about user account, which is used by server
- to access file system on behalf of the client.
-
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
-class DoneOpen(object):
- def doneOpen(self, token, error, handle):
- pass
-
-class DoneClose(object):
- def doneClose(self, token, error):
- pass
-
-class DoneRead(object):
- def doneRead(self, token, error, data, eof):
- pass
-
-class DoneWrite(object):
- def doneWrite(self, token, error):
- pass
-
-class DoneStat(object):
- def doneStat(self, token, error, attrs):
- pass
-
-class DoneSetStat(object):
- def doneSetStat(self, token, error):
- pass
-
-class DoneReadDir(object):
- def doneReadDir(self, token, error, entries, eof):
- pass
-
-class DoneMkDir(object):
- def doneMkDir(self, token, error):
- pass
-
-class DoneRemove(object):
- def doneRemove(self, token, error):
- pass
-
-class DoneRoots(object):
- def doneRoots(self, token, error, entries):
- pass
-
-class DoneRealPath(object):
- def doneRealPath(self, token, error, path):
- pass
-
-class DoneRename(object):
- def doneRename(self, token, error):
- pass
-
-class DoneReadLink(object):
- def doneReadLink(self, token, error, path):
- pass
-
-class DoneSymLink(object):
- def doneSymLink(self, token, error):
- pass
-
-class DoneCopy(object):
- def doneCopy(self, token, error):
- pass
-
-class DoneUser(object):
- def doneUser(self, token, error, real_uid, effective_uid, real_gid, effective_gid, home):
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+File System service provides file transfer (and more generally file
+system access) functionality in TCF. The service design is
+derived from SSH File Transfer Protocol specifications.
+
+ Request Synchronization and Reordering
+
+The protocol and implementations MUST process requests relating to
+the same file in the order in which they are received. In other
+words, if an application submits multiple requests to the server, the
+results in the responses will be the same as if it had sent the
+requests one at a time and waited for the response in each case. For
+example, the server may process non-overlapping read/write requests
+to the same file in parallel, but overlapping reads and writes cannot
+be reordered or parallelized. However, there are no ordering
+restrictions on the server for processing requests from two different
+file transfer connections. The server may interleave and parallelize
+them at will.
+
+There are no restrictions on the order in which responses to
+outstanding requests are delivered to the client, except that the
+server must ensure fairness in the sense that processing of no
+request will be indefinitely delayed even if the client is sending
+other requests so that there are multiple outstanding requests all
+the time.
+
+There is no limit on the number of outstanding (non-acknowledged)
+requests that the client may send to the server. In practice this is
+limited by the buffering available on the data stream and the queuing
+performed by the server. If the server's queues are full, it should
+not read any more data from the stream, and flow control will prevent
+the client from sending more requests.
+
+ File Names
+
+This protocol represents file names as strings. File names are
+assumed to use the slash ('/') character as a directory separator.
+
+File names starting with a slash are "absolute", and are relative to
+the root of the file system. Names starting with any other character
+are relative to the user's default directory (home directory). Client
+can use 'user()' command to retrieve current user home directory.
+
+Servers SHOULD interpret a path name component ".." as referring to
+the parent directory, and "." as referring to the current directory.
+If the server implementation limits access to certain parts of the
+file system, it must be extra careful in parsing file names when
+enforcing such restrictions. There have been numerous reported
+security bugs where a ".." in a path name has allowed access outside
+the intended area.
+
+An empty path name is valid, and it refers to the user's default
+directory (usually the user's home directory).
+
+Otherwise, no syntax is defined for file names by this specification.
+Clients should not make any other assumptions however, they can
+splice path name components returned by readdir() together
+using a slash ('/') as the separator, and that will work as expected.
+"""
+
+from tcf import services
+
+# Service name.
+NAME = "FileSystem"
+
+# Flags to be used with open() method.
+
+# Open the file for reading.
+TCF_O_READ = 0x00000001
+
+# Open the file for writing. If both this and TCF_O_READ are
+# specified, the file is opened for both reading and writing.
+TCF_O_WRITE = 0x00000002
+
+# Force all writes to append data at the end of the file.
+TCF_O_APPEND = 0x00000004
+
+# If this flag is specified, then a new file will be created if one
+# does not already exist (if TCF_O_TRUNC is specified, the new file will
+# be truncated to zero length if it previously exists).
+TCF_O_CREAT = 0x00000008
+
+# Forces an existing file with the same name to be truncated to zero
+# length when creating a file by specifying TCF_O_CREAT.
+# TCF_O_CREAT MUST also be specified if this flag is used.
+TCF_O_TRUNC = 0x00000010
+
+# Causes the request to fail if the named file already exists.
+# TCF_O_CREAT MUST also be specified if this flag is used.
+TCF_O_EXCL = 0x00000020
+
+# Flags to be used together with FileAttrs.
+# The flags specify which of the fields are present. Those fields
+# for which the corresponding flag is not set are not present (not
+# included in the message).
+ATTR_SIZE = 0x00000001
+ATTR_UIDGID = 0x00000002
+ATTR_PERMISSIONS = 0x00000004
+ATTR_ACMODTIME = 0x00000008
+
+class FileAttrs(object):
+ """
+ FileAttrs is used both when returning file attributes from
+ the server and when sending file attributes to the server. When
+ sending it to the server, the flags field specifies which attributes
+ are included, and the server will use default values for the
+ remaining attributes (or will not modify the values of remaining
+ attributes). When receiving attributes from the server, the flags
+ specify which attributes are included in the returned data. The
+ server normally returns all attributes it knows about.
+
+ Fields:
+ The 'flags' specify which of the fields are present.
+ The 'size' field specifies the size of the file in bytes.
+ The 'uid' and 'gid' fields contain numeric Unix-like user and group
+ identifiers, respectively.
+ The 'permissions' field contains a bit mask of file permissions as
+ defined by posix [1].
+ The 'atime' and 'mtime' contain the access and modification times of
+ the files, respectively. They are represented as milliseconds from
+ midnight Jan 1, 1970 in UTC.
+ attributes - Additional (non-standard) attributes.
+ """
+ def __init__(self, flags, size, uid, gid, permissions, atime, mtime, attributes):
+ self.flags = flags
+ self.size = size
+ self.uid = uid
+ self.gid = gid
+ self.permissions = permissions
+ self.atime = atime
+ self.mtime = mtime
+ self.attributes = attributes
+
+ def isFile(self):
+ """
+ Determines if the file system object is a file on the remote file system.
+
+ @return True if and only if the object on the remote system can be considered to have "contents" that
+ have the potential to be read and written as a byte stream.
+ """
+ if (self.flags & ATTR_PERMISSIONS) == 0: return False
+ return (self.permissions & S_IFMT) == S_IFREG
+
+ def isDirectory(self):
+ """
+ Determines if the file system object is a directory on the remote file system.
+
+ @return True if and only if the object on the remote system is a directory.
+ That is, it contains entries that can be interpreted as other files.
+ """
+ if (self.flags & ATTR_PERMISSIONS) == 0: return False
+ return (self.permissions & S_IFMT) == S_IFDIR
+
+# The following flags are defined for the 'permissions' field:
+S_IFMT = 0170000 # bitmask for the file type bitfields
+S_IFSOCK = 0140000 # socket
+S_IFLNK = 0120000 # symbolic link
+S_IFREG = 0100000 # regular file
+S_IFBLK = 0060000 # block device
+S_IFDIR = 0040000 # directory
+S_IFCHR = 0020000 # character device
+S_IFIFO = 0010000 # fifo
+S_ISUID = 0004000 # set UID bit
+S_ISGID = 0002000 # set GID bit (see below)
+S_ISVTX = 0001000 # sticky bit (see below)
+S_IRWXU = 00700 # mask for file owner permissions
+S_IRUSR = 00400 # owner has read permission
+S_IWUSR = 00200 # owner has write permission
+S_IXUSR = 00100 # owner has execute permission
+S_IRWXG = 00070 # mask for group permissions
+S_IRGRP = 00040 # group has read permission
+S_IWGRP = 00020 # group has write permission
+S_IXGRP = 00010 # group has execute permission
+S_IRWXO = 00007 # mask for permissions for others (not in group)
+S_IROTH = 00004 # others have read permission
+S_IWOTH = 00002 # others have write permission
+S_IXOTH = 00001 # others have execute permission
+
+class DirEntry(object):
+ """
+ Directory entry.
+ Fields:
+ 'filename' is a file name being returned. It is a relative name within
+ the directory, without any path components
+ 'longname' is an expanded format for the file name, similar to what
+ is returned by "ls -l" on Unix systems.
+ The format of the 'longname' field is unspecified by this protocol.
+ It MUST be suitable for use in the output of a directory listing
+ command (in fact, the recommended operation for a directory listing
+ command is to simply display this data). However, clients SHOULD NOT
+ attempt to parse the longname field for file attributes they SHOULD
+ use the attrs field instead.
+ 'attrs' is the attributes of the file.
+ """
+ def __init__(self, filename, longname, attrs):
+ self.filename = filename
+ self.longname = longname
+ self.attrs = attrs
+
+class FileHandle(object):
+ def __init__(self, service, id):
+ self.service = service
+ self.id = id
+
+ def getService(self):
+ return self.service
+
+ def __str__(self):
+ return "[File Handle '%s'" % self.id
+
+# Service specific error codes.
+
+# Indicates end-of-file condition for read() it means that no
+# more data is available in the file, and for readdir() it
+# indicates that no more files are contained in the directory.
+STATUS_EOF = 0x10001
+
+# This code is returned when a reference is made to a file which
+# should exist but doesn't.
+STATUS_NO_SUCH_FILE = 0x10002
+
+# is returned when the authenticated user does not have sufficient
+# permissions to perform the operation.
+STATUS_PERMISSION_DENIED = 0x10003
+
+class FileSystemException(IOError):
+ """
+ The class to represent File System error reports.
+ """
+ def __init__(self, message_or_exception):
+ if isinstance(message_or_exception, str):
+ super(FileSystemException, self).__init__(message_or_exception)
+ elif isinstance(message_or_exception, Exception):
+ self.caused_by = message_or_exception
+ def getStatus(self):
+ """
+ Get error code. The code can be standard TCF error code or
+ one of service specific codes, see STATUS_*.
+ @return error code.
+ """
+ raise NotImplementedError("Abstract methods")
+
+class FileSystemService(services.Service):
+ def getName(self):
+ return NAME
+
+ def open(self, file_name, flags, attrs, done):
+ """
+ Open or create a file on a remote system.
+
+ @param file_name specifies the file name. See 'File Names' for more information.
+ @param flags is a bit mask of TCF_O_* flags.
+ @param attrs specifies the initial attributes for the file.
+ Default values will be used for those attributes that are not specified.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def close(self, handle, done):
+ """
+ Close a file on a remote system.
+
+ @param handle is a handle previously returned in the response to
+ open() or opendir().
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def read(self, handle, offset, len, done):
+ """
+ Read bytes from an open file.
+ In response to this request, the server will read as many bytes as it
+ can from the file (up to 'len'), and return them in a byte array.
+ If an error occurs or EOF is encountered, the server may return
+ fewer bytes then requested. Call back method doneRead() argument 'error'
+ will be not None in case of error, and argument 'eof' will be
+ True in case of EOF. For normal disk files, it is guaranteed
+ that this will read the specified number of bytes, or up to end of file
+ or error. For e.g. device files this may return fewer bytes than requested.
+
+ @param handle is an open file handle returned by open().
+ @param offset is the offset (in bytes) relative
+ to the beginning of the file from where to start reading.
+ If offset < 0 then reading starts from current position in the file.
+ @param len is the maximum number of bytes to read.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def write(self, handle, offset, data, data_pos, data_size, done):
+ """
+ Write bytes into an open file.
+ The write will extend the file if writing beyond the end of the file.
+ It is legal to write way beyond the end of the file the semantics
+ are to write zeroes from the end of the file to the specified offset
+ and then the data.
+
+ @param handle is an open file handle returned by open().
+ @param offset is the offset (in bytes) relative
+ to the beginning of the file from where to start writing.
+ If offset < 0 then writing starts from current position in the file.
+ @param data is byte array that contains data for writing.
+ @param data_pos if offset in 'data' of first byte to write.
+ @param data_size is the number of bytes to write.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def stat(self, path, done):
+ """
+ Retrieve file attributes.
+
+ @param path - specifies the file system object for which
+ status is to be returned.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def lstat(self, path, done):
+ """
+ Retrieve file attributes.
+ Unlike 'stat()', 'lstat()' does not follow symbolic links.
+
+ @param path - specifies the file system object for which
+ status is to be returned.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def fstat(self, handle, done):
+ """
+ Retrieve file attributes for an open file (identified by the file handle).
+
+ @param handle is a file handle returned by 'open()'.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def setstat(self, path, attrs, done):
+ """
+ Set file attributes.
+ This request is used for operations such as changing the ownership,
+ permissions or access times, as well as for truncating a file.
+ An error will be returned if the specified file system object does
+ not exist or the user does not have sufficient rights to modify the
+ specified attributes.
+
+ @param path specifies the file system object (e.g. file or directory)
+ whose attributes are to be modified.
+ @param attrs specifies the modifications to be made to file attributes.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def fsetstat(self, handle, attrs, done):
+ """
+ Set file attributes for an open file (identified by the file handle).
+ This request is used for operations such as changing the ownership,
+ permissions or access times, as well as for truncating a file.
+
+ @param handle is a file handle returned by 'open()'.
+ @param attrs specifies the modifications to be made to file attributes.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def opendir(self, path, done):
+ """
+ The opendir() command opens a directory for reading.
+ Once the directory has been successfully opened, files (and
+ directories) contained in it can be listed using readdir() requests.
+ When the client no longer wishes to read more names from the
+ directory, it SHOULD call close() for the handle. The handle
+ should be closed regardless of whether an error has occurred or not.
+
+ @param path - name of the directory to be listed (without any trailing slash).
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def readdir(self, handle, done):
+ """
+ The files in a directory can be listed using the opendir() and
+ readdir() requests. Each readdir() request returns one
+ or more file names with full file attributes for each file. The
+ client should call readdir() repeatedly until it has found the
+ file it is looking for or until the server responds with a
+ message indicating an error or end of file. The client should then
+ close the handle using the close() request.
+ Note: directory entries "." and ".." are NOT included into readdir()
+ response.
+ @param handle - file handle created by opendir()
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def mkdir(self, path, attrs, done):
+ """
+ Create a directory on the server.
+
+ @param path - specifies the directory to be created.
+ @param attrs - new directory attributes.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def rmdir(self, path, done):
+ """
+ Remove a directory.
+ An error will be returned if no directory
+ with the specified path exists, or if the specified directory is not
+ empty, or if the path specified a file system object other than a
+ directory.
+
+ @param path - specifies the directory to be removed.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def roots(self, done):
+ """
+ Retrieve file system roots - top level file system objects.
+ UNIX file system can report just one root with path "/". Other types of systems
+ can have more the one root. For example, Windows server can return multiple roots:
+ one per disc (e.g. "/C:/", "/D:/", etc.). Note: even Windows implementation of
+ the service must use forward slash as directory separator, and must start
+ absolute path with "/". Server should implement proper translation of
+ protocol file names to OS native names and back.
+
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def remove(self, file_name, done):
+ """
+ Remove a file or symbolic link.
+ This request cannot be used to remove directories.
+
+ @param file_name is the name of the file to be removed.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def realpath(self, path, done):
+ """
+ Canonicalize any given path name to an absolute path.
+ This is useful for converting path names containing ".." components or
+ relative pathnames without a leading slash into absolute paths.
+
+ @param path specifies the path name to be canonicalized.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def rename(self, old_path, new_path, done):
+ """
+ Rename a file.
+ It is an error if there already exists a file
+ with the name specified by 'new_path'. The server may also fail rename
+ requests in other situations, for example if 'old_path' and 'new_path'
+ point to different file systems on the server.
+
+ @param old_path is the name of an existing file or directory.
+ @param new_path is the new name for the file or directory.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def readlink(self, path, done):
+ """
+ Read the target of a symbolic link.
+
+ @param path specifies the path name of the symbolic link to be read.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def symlink(self, link_path, target_path, done):
+ """
+ Create a symbolic link on the server.
+
+ @param link_path specifies the path name of the symbolic link to be created.
+ @param target_path specifies the target of the symbolic link.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def copy(self, src_path, dst_path, copy_permissions, copy_ownership, done):
+ """
+ Copy a file on remote system.
+
+ @param src_path specifies the path name of the file to be copied.
+ @param dst_path specifies destination file name.
+ @param copy_permissions - if True then copy source file permissions.
+ @param copy_ownership - if True then copy source file UID and GID.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def user(self, done):
+ """
+ Retrieve information about user account, which is used by server
+ to access file system on behalf of the client.
+
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+class DoneOpen(object):
+ def doneOpen(self, token, error, handle):
+ pass
+
+class DoneClose(object):
+ def doneClose(self, token, error):
+ pass
+
+class DoneRead(object):
+ def doneRead(self, token, error, data, eof):
+ pass
+
+class DoneWrite(object):
+ def doneWrite(self, token, error):
+ pass
+
+class DoneStat(object):
+ def doneStat(self, token, error, attrs):
+ pass
+
+class DoneSetStat(object):
+ def doneSetStat(self, token, error):
+ pass
+
+class DoneReadDir(object):
+ def doneReadDir(self, token, error, entries, eof):
+ pass
+
+class DoneMkDir(object):
+ def doneMkDir(self, token, error):
+ pass
+
+class DoneRemove(object):
+ def doneRemove(self, token, error):
+ pass
+
+class DoneRoots(object):
+ def doneRoots(self, token, error, entries):
+ pass
+
+class DoneRealPath(object):
+ def doneRealPath(self, token, error, path):
+ pass
+
+class DoneRename(object):
+ def doneRename(self, token, error):
+ pass
+
+class DoneReadLink(object):
+ def doneReadLink(self, token, error, path):
+ pass
+
+class DoneSymLink(object):
+ def doneSymLink(self, token, error):
+ pass
+
+class DoneCopy(object):
+ def doneCopy(self, token, error):
+ pass
+
+class DoneUser(object):
+ def doneUser(self, token, error, real_uid, effective_uid, real_gid, effective_gid, home):
+ pass
diff --git a/python/src/tcf/services/linenumbers.py b/python/src/tcf/services/linenumbers.py
index d026ecd12..fe3703def 100644
--- a/python/src/tcf/services/linenumbers.py
+++ b/python/src/tcf/services/linenumbers.py
@@ -1,132 +1,132 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Line numbers service associates locations in the source files with the corresponding
-machine instruction addresses in the executable object.
-"""
-
-from tcf import services
-
-NAME = "LineNumbers"
-
-class CodeArea(object):
- """
- A CodeArea represents a continues area in source text mapped to
- continues range of code addresses.
- Line and columns are counted starting from 1.
- File name can be a relative path, in this case the client should
- use the CodeArea directory name as origin for the path.
- File and directory names are valid on a host where code was compiled.
- It is client responsibility to map names to local host file system.
- """
- def __init__(self, directory, file, start_line, start_column,
- end_line, end_column, start_address, end_address, isa,
- is_statement, basic_block, prologue_end, epilogue_begin):
- self.directory = directory
- self.file = file
- self.start_line = start_line
- self.start_column = start_column
- self.end_line = end_line
- self.end_column = end_column
- self.start_address = start_address
- self.end_address = end_address
- self.isa = isa
- self.is_statement = is_statement
- self.basic_block = basic_block
- self.prologue_end = prologue_end
- self.epilogue_begin = epilogue_begin
-
- def __eq__(self, o):
- if self is o: return True
- if not isinstance(o, CodeArea): return False
- if self.start_line != o.start_line: return False
- if self.start_column != o.start_column: return False
- if self.end_line != o.end_line: return False
- if self.end_column != o.end_column: return False
- if self.isa != o.isa: return False
- if self.is_statement != o.is_statement: return False
- if self.basic_block != o.basic_block: return False
- if self.prologue_end != o.prologue_end: return False
- if self.epilogue_begin != o.epilogue_begin: return False
- if self.start_address != o.start_address: return False
- if self.end_address != o.end_address: return False
- if self.file != o.file: return False
- if self.directory != o.directory: return False
- return True
-
- def __hash__(self):
- h = 0
- if file: h += hash(file)
- return h + self.start_line + self.start_column + self.end_line + self.end_column
-
- def __str__(self):
- import cStringIO
- bf = cStringIO.StringIO()
- bf.write('[')
- if self.directory:
- bf.write(self.directory)
- bf.write(':')
- if self.file:
- bf.write(self.file)
- bf.write(':')
- bf.write(str(self.start_line))
- if self.start_column:
- bf.write('.')
- bf.write(str(self.start_column))
- bf.write("..")
- bf.write(str(self.end_line))
- if self.end_column:
- bf.write('.')
- bf.write(str(self.end_column))
- bf.write(" -> ")
- if self.start_address:
- bf.write("0x")
- bf.write(hex(self.start_address))
- else:
- bf.write('0')
- bf.write("..")
- if self.end_address:
- bf.write("0x")
- bf.write(hex(self.end_address))
- else:
- bf.write('0')
- if self.isa:
- bf.write(",isa ")
- bf.write(str(self.isa))
- if self.is_statement:
- bf.write(",statement")
- if self.basic_block:
- bf.write(",basic block")
- if self.prologue_end:
- bf.write(",prologue end")
- if self.epilogue_begin:
- bf.write(",epilogue begin")
- bf.write(']')
- return bf.getvalue()
-
-class LineNumbersService(services.Service):
- def getName(self):
- return NAME
-
- def mapToSource(self, context_id, start_address, end_address, done):
- raise NotImplementedError("Abstract method")
-
- def mapToMemory(self, context_id, file, line, column, done):
- raise NotImplementedError("Abstract method")
-
-class DoneMapToSource(object):
- def doneMapToSource(self, token, error, areas):
- pass
-
-class DoneMapToMemory(object):
- def doneMapToMemory(self, token, error, areas):
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Line numbers service associates locations in the source files with the corresponding
+machine instruction addresses in the executable object.
+"""
+
+from tcf import services
+
+NAME = "LineNumbers"
+
+class CodeArea(object):
+ """
+ A CodeArea represents a continues area in source text mapped to
+ continues range of code addresses.
+ Line and columns are counted starting from 1.
+ File name can be a relative path, in this case the client should
+ use the CodeArea directory name as origin for the path.
+ File and directory names are valid on a host where code was compiled.
+ It is client responsibility to map names to local host file system.
+ """
+ def __init__(self, directory, file, start_line, start_column,
+ end_line, end_column, start_address, end_address, isa,
+ is_statement, basic_block, prologue_end, epilogue_begin):
+ self.directory = directory
+ self.file = file
+ self.start_line = start_line
+ self.start_column = start_column
+ self.end_line = end_line
+ self.end_column = end_column
+ self.start_address = start_address
+ self.end_address = end_address
+ self.isa = isa
+ self.is_statement = is_statement
+ self.basic_block = basic_block
+ self.prologue_end = prologue_end
+ self.epilogue_begin = epilogue_begin
+
+ def __eq__(self, o):
+ if self is o: return True
+ if not isinstance(o, CodeArea): return False
+ if self.start_line != o.start_line: return False
+ if self.start_column != o.start_column: return False
+ if self.end_line != o.end_line: return False
+ if self.end_column != o.end_column: return False
+ if self.isa != o.isa: return False
+ if self.is_statement != o.is_statement: return False
+ if self.basic_block != o.basic_block: return False
+ if self.prologue_end != o.prologue_end: return False
+ if self.epilogue_begin != o.epilogue_begin: return False
+ if self.start_address != o.start_address: return False
+ if self.end_address != o.end_address: return False
+ if self.file != o.file: return False
+ if self.directory != o.directory: return False
+ return True
+
+ def __hash__(self):
+ h = 0
+ if file: h += hash(file)
+ return h + self.start_line + self.start_column + self.end_line + self.end_column
+
+ def __str__(self):
+ import cStringIO
+ bf = cStringIO.StringIO()
+ bf.write('[')
+ if self.directory:
+ bf.write(self.directory)
+ bf.write(':')
+ if self.file:
+ bf.write(self.file)
+ bf.write(':')
+ bf.write(str(self.start_line))
+ if self.start_column:
+ bf.write('.')
+ bf.write(str(self.start_column))
+ bf.write("..")
+ bf.write(str(self.end_line))
+ if self.end_column:
+ bf.write('.')
+ bf.write(str(self.end_column))
+ bf.write(" -> ")
+ if self.start_address:
+ bf.write("0x")
+ bf.write(hex(self.start_address))
+ else:
+ bf.write('0')
+ bf.write("..")
+ if self.end_address:
+ bf.write("0x")
+ bf.write(hex(self.end_address))
+ else:
+ bf.write('0')
+ if self.isa:
+ bf.write(",isa ")
+ bf.write(str(self.isa))
+ if self.is_statement:
+ bf.write(",statement")
+ if self.basic_block:
+ bf.write(",basic block")
+ if self.prologue_end:
+ bf.write(",prologue end")
+ if self.epilogue_begin:
+ bf.write(",epilogue begin")
+ bf.write(']')
+ return bf.getvalue()
+
+class LineNumbersService(services.Service):
+ def getName(self):
+ return NAME
+
+ def mapToSource(self, context_id, start_address, end_address, done):
+ raise NotImplementedError("Abstract method")
+
+ def mapToMemory(self, context_id, file, line, column, done):
+ raise NotImplementedError("Abstract method")
+
+class DoneMapToSource(object):
+ def doneMapToSource(self, token, error, areas):
+ pass
+
+class DoneMapToMemory(object):
+ def doneMapToMemory(self, token, error, areas):
+ pass
diff --git a/python/src/tcf/services/local/LocatorService.py b/python/src/tcf/services/local/LocatorService.py
index 5d8f43bc2..5a9271548 100644
--- a/python/src/tcf/services/local/LocatorService.py
+++ b/python/src/tcf/services/local/LocatorService.py
@@ -1,807 +1,807 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Locator service uses transport layer to search
-for peers and to collect and maintain up-to-date
-data about peer's attributes.
-"""
-
-import threading, time, socket, cStringIO
-from tcf.services import locator
-from tcf.util import logging
-from tcf.channel import fromJSONSequence, toJSONSequence
-from tcf.channel.ChannelProxy import ChannelProxy
-from tcf import protocol, services, channel, peer, errors
-
-# Flag indicating whether tracing of the the discovery activity is enabled.
-__TRACE_DISCOVERY__ = False
-
-class SubNet(object):
- def __init__(self, prefix_length, address, broadcast):
- self.prefix_length = prefix_length
- self.address = address
- self.broadcast = broadcast
- self.last_slaves_req_time = 0
- def contains(self, addr):
- if addr is None or self.address is None: return False
- a1 = addr.getAddress()
- a2 = self.address.getAddress()
- if len(a1) != len(a2): return False
- i = 0
- if self.prefix_length <= len(a1) * 8:
- l = self.prefix_length
- else:
- l = len(a1) * 8
- while i + 8 <= l:
- n = i / 8
- if a1[n] != a2[n]: return False
- i += 8
- while i < l:
- n = i / 8
- m = 1 << (7 - i % 8)
- if (a1[n] & m) != (a2[n] & m): return False
- i += 1
- return True
- def __eq__(self, o):
- if not isinstance(o, SubNet): return False
- return self.prefix_length == o.prefix_length and \
- self.broadcast == o.broadcast and \
- self.address == o.address
- def __hash__(self):
- return hash(self.address)
- def __str__(self):
- return "%s/%d" % (self.address.getHostAddress(), self.prefix_length)
-
-class Slave(object):
- # Time of last packet receiver from self slave
- last_packet_time = 0
- #Time of last REQ_SLAVES packet received from self slave
- last_req_slaves_time = 0
-
- def __init__(self, address, port):
- self.address = address
- self.port = port
- def __str__(self):
- return "%s/%d" % (self.address.getHostAddress(), self.port)
-
-class AddressCacheItem(object):
- address = None
- time_stamp = 0
- used = False
- def __init__(self, host):
- self.host = host
-
-class InetAddress(object):
- "Mimicking Java InetAddress class"
- def __init__(self, host, addr):
- self.host = host
- self.addr = addr
- def getAddress(self):
- return socket.inet_aton(self.addr)
- def getHostAddress(self):
- return self.addr
- def __eq__(self, other):
- if not isinstance(other, InetAddress): return False
- return self.addr == other.addr
- def __str__(self):
- return "%s/%s" % (self.host or "", self.addr)
-
-class InputPacket(object):
- "Wrapper for UDP packet data."
- def __init__(self, data, addr, port):
- self.data = data
- self.addr = addr
- self.port = port
- def getLength(self):
- return len(self.data)
- def getData(self):
- return self.data
- def getPort(self):
- return self.port
- def getAddress(self):
- return self.addr
- def __str__(self):
- return "[address=%s,port=%d,data=\"%s\"]" % (self.getAddress(), self.getPort(), self.data)
-
-DISCOVEY_PORT = 1534
-MAX_PACKET_SIZE = 9000 - 40 - 8
-PREF_PACKET_SIZE = 1500 - 40 - 8
-
-# TODO: research usage of DNS-SD (DNS Service Discovery) to discover TCF peers
-class LocatorService(locator.LocatorService):
- locator = None
- peers = {} # str->Peer
- listeners = [] # list of LocatorListener
- error_log = set() # set of str
-
- addr_cache = {} # str->AddressCacheItem
- addr_request = False
- local_peer = None
- last_master_packet_time = 0
-
- @classmethod
- def getLocalPeer(cls):
- return cls.local_peer
-
- @classmethod
- def getListeners(cls):
- return cls.listeners[:]
-
- @classmethod
- def startup(cls):
- if cls.locator:
- cls.locator._startup()
-
- @classmethod
- def shutdown(cls):
- if cls.locator:
- cls.locator._shutdown()
-
- def __init__(self):
- self._error_log_lock = threading.RLock()
- self._alive = False
- LocatorService.locator = self
- LocatorService.local_peer = peer.LocalPeer()
-
- def _startup(self):
- if self._alive: return
- self._alive = True
- self._addr_cache_lock = threading.Condition()
- self.subnets = set()
- self.slaves = []
- self.inp_buf = bytearray(MAX_PACKET_SIZE)
- self.out_buf = bytearray(MAX_PACKET_SIZE)
- service = self
- class TimerThread(threading.Thread):
- def __init__(self, callable):
- self._callable = callable
- super(TimerThread, self).__init__()
- def run(self):
- while service._alive:
- try:
- time.sleep(locator.DATA_RETENTION_PERIOD / 4 / 1000.)
- protocol.invokeAndWait(self._callable)
- except RuntimeError:
- # TCF event dispatch is shut down
- return
- except Exception as x:
- service._log("Unhandled exception in TCF discovery timer thread", x)
- self.timer_thread = TimerThread(self.__refresh_timer)
- class DNSLookupThread(threading.Thread):
- def run(self):
- while service._alive:
- try:
- itemSet = None
- with service._addr_cache_lock:
- if not LocatorService.addr_request:
- service._addr_cache_lock.wait(locator.DATA_RETENTION_PERIOD)
- msec = int(time.time() * 1000)
- for host, a in LocatorService.addr_cache.items():
- if a.time_stamp + locator.DATA_RETENTION_PERIOD * 10 < msec:
- if a.used:
- if itemSet is None: itemSet = set()
- itemSet.add(a)
- else:
- del LocatorService.addr_cache[host]
- LocatorService.addr_request = False
- if itemSet is not None:
- for a in itemSet:
- addr = None
- try:
- addr = socket.gethostbyname(a.host)
- except socket.gaierror:
- pass
- with service._addr_cache_lock:
- if addr is None:
- a.address = None
- else:
- a.address = InetAddress(a.host, addr)
- a.time_stamp = msec
- a.used = False
- except Exception as x:
- service._log("Unhandled exception in TCF discovery DNS lookup thread", x)
- self.dns_lookup_thread = DNSLookupThread()
- class InputThread(threading.Thread):
- def __init__(self, callable):
- self._callable = callable
- super(InputThread, self).__init__()
- def run(self):
- try:
- while service._alive:
- sock = service.socket
- try:
- data, addr = sock.recvfrom(MAX_PACKET_SIZE)
- p = InputPacket(data, InetAddress(None, addr[0]), addr[1])
- protocol.invokeAndWait(self._callable, p)
- except RuntimeError:
- # TCF event dispatch is shutdown
- return
- except socket.error as x:
- if sock != service.socket: continue
- # frequent error on windows, unknown reason
- if x.errno == 10054: continue
- port = sock.getsockname()[1]
- service._log("Cannot read from datagram socket at port %d" % port, x)
- time.sleep(2)
- except Exception as x:
- service._log("Unhandled exception in socket reading thread", x)
- self.input_thread = InputThread(self.__handleDatagramPacket)
- try:
- self.loopback_addr = InetAddress(None, "127.0.0.1")
- self.out_buf[0:8] = 'TCF%s\0\0\0\0' % locator.CONF_VERSION
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- try:
- self.socket.bind(('', DISCOVEY_PORT))
- if __TRACE_DISCOVERY__:
- logging.trace("Became the master agent (bound to port %d)" % self.socket.getsockname()[1])
- except socket.error as x:
- self.socket.bind(('', 0))
- if __TRACE_DISCOVERY__:
- logging.trace("Became a slave agent (bound to port %d)" % self.socket.getsockname()[1])
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
- self.input_thread.setName("TCF Locator Receiver")
- self.timer_thread.setName("TCF Locator Timer")
- self.dns_lookup_thread.setName("TCF Locator DNS Lookup")
- self.input_thread.setDaemon(True)
- self.timer_thread.setDaemon(True)
- self.dns_lookup_thread.setDaemon(True)
- self.input_thread.start()
- self.timer_thread.start()
- self.dns_lookup_thread.start()
- class LocatorListener(locator.LocatorListener):
- def peerAdded(self, peer):
- service._sendPeerInfo(peer, None, 0)
- def peerChanged(self, peer):
- service._sendPeerInfo(peer, None, 0)
- self.listeners.append(LocatorListener())
- self.__refreshSubNetList()
- self.__sendPeersRequest(None, 0)
- self.__sendAll(None, 0, None, int(time.time() * 1000))
- except Exception as x:
- self._log("Cannot open UDP socket for TCF discovery protocol", x)
-
- def _shutdown(self):
- if self._alive:
- self._alive = False
-
- def __makeErrorReport(self, code, msg):
- err = {}
- err[errors.ERROR_TIME] = int(time.time() * 1000)
- err[errors.ERROR_CODE] = code
- err[errors.ERROR_FORMAT] = msg
- return err
-
- def __command(self, channel, token, name, data):
- try:
- if name == "redirect":
- peer_id = fromJSONSequence(data)[0]
- _peer = self.peers.get(peer_id)
- if _peer is None:
- error = self.__makeErrorReport(errors.TCF_ERROR_UNKNOWN_PEER, "Unknown peer ID")
- channel.sendResult(token, toJSONSequence((error,)))
- return
- channel.sendResult(token, toJSONSequence((None,)))
- if isinstance(_peer, peer.LocalPeer):
- channel.sendEvent(protocol.getLocator(), "Hello", toJSONSequence((channel.getLocalServices(),)))
- return
- ChannelProxy(channel, _peer.openChannel())
- elif name == "sync":
- channel.sendResult(token, None)
- elif name == "getPeers":
- arr = []
- for p in self.peers.values():
- arr.append(p.getAttributes())
- channel.sendResult(token, toJSONSequence((None, arr)))
- else:
- channel.rejectCommand(token)
- except Exception as x:
- channel.terminate(x)
-
- def _log(self, msg, x):
- if not self._alive: return
- # Don't report same error multiple times to avoid filling up the log file.
- with self._error_log_lock:
- if msg in self.error_log: return
- self.error_log.add(msg)
- protocol.log(msg, x)
-
- def __getInetAddress(self, host):
- if not host: return None
- with self._addr_cache_lock:
- i = self.addr_cache.get(host)
- if i is None:
- i = AddressCacheItem(host)
- ch = host[0]
- if ch == '[' or ch == ':' or ch >= '0' and ch <= '9':
- try:
- addr = socket.gethostbyname(host)
- i.address = InetAddress(host, addr)
- except socket.gaierror:
- pass
- i.time_stamp = int(time.time() * 1000)
- else:
- # socket.gethostbyname() can cause long delay - delegate to background thread
- LocatorService.addr_request = True
- self._addr_cache_lock.notify()
- self.addr_cache[host] = i
- i.used = True
- return i.address
-
- def __refresh_timer(self):
- tm = int(time.time() * 1000)
- # Cleanup slave table
- if self.slaves:
- i = 0
- while i < len(self.slaves):
- s = self.slaves[i]
- if s.last_packet_time + locator.DATA_RETENTION_PERIOD < tm:
- del self.slaves[i]
- else:
- i += 1
-
- # Cleanup peers table
- stale_peers = None
- for p in self.peers.values():
- if isinstance(p, peer.RemotePeer):
- if p.getLastUpdateTime() + locator.DATA_RETENTION_PERIOD < tm:
- if stale_peers == None: stale_peers = []
- stale_peers.append(p)
- if stale_peers is not None:
- for p in stale_peers: p.dispose()
-
- # Try to become a master
- port = self.socket.getsockname()[1]
- if port != DISCOVEY_PORT and \
- self.last_master_packet_time + locator.DATA_RETENTION_PERIOD / 2 <= tm:
- s0 = self.socket
- s1 = None
- try:
- s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- s1.bind(DISCOVEY_PORT)
- s1.setsockopt(socket.SOL_UDP, socket.SO_BROADCAST, 1)
- self.socket = s1
- s0.close()
- except:
- pass
- self.__refreshSubNetList()
- if port != DISCOVEY_PORT:
- for subnet in self.subnets:
- self.__addSlave(subnet.address, port, tm, tm)
- self.__sendAll(None, 0, None, tm)
-
- def __addSlave(self, addr, port, timestamp, time_now):
- for s in self.slaves:
- if s.port == port and s.address == addr:
- if s.last_packet_time < timestamp: s.last_packet_time = timestamp
- return s
- s = Slave(addr, port)
- s.last_packet_time = timestamp
- self.slaves.append(s)
- self.__sendPeersRequest(addr, port)
- self.__sendAll(addr, port, s, time_now)
- self.__sendSlaveInfo(s, time_now)
- return s
-
- def __refreshSubNetList(self):
- subNetSet = set()
- try:
- self.__getSubNetList(subNetSet)
- except Exception as x:
- self._log("Cannot get list of network interfaces", x)
- for s in tuple(self.subnets):
- if s in subNetSet: continue
- self.subnets.remove(s)
- for s in subNetSet:
- if s in self.subnets: continue
- self.subnets.add(s)
- if __TRACE_DISCOVERY__:
- str = cStringIO.StringIO()
- str.write("Refreshed subnet list:")
- for subnet in self.subnets:
- str.write("\n\t* address=%s, broadcast=%s" % (subnet.address, subnet.broadcast))
- logging.trace(str.getvalue())
-
- def __getSubNetList(self, set):
- # TODO iterate over network interfaces to get proper broadcast addresses
- hostname = socket.gethostname()
- _, _, addresses = socket.gethostbyname_ex(hostname)
- if not "127.0.0.1" in addresses:
- addresses.append("127.0.0.1")
- for address in addresses:
- rawaddr = socket.inet_aton(address)
- if len(rawaddr) != 4: continue
- rawaddr = rawaddr[:3] + '\xFF'
- broadcast = socket.inet_ntoa(rawaddr)
- set.add(SubNet(24, InetAddress(hostname, address), InetAddress(None, broadcast)))
-
- def __getUTF8Bytes(self, s):
- return s.encode("UTF-8")
-
- # Used for tracing
- packetTypes = [
- None,
- "CONF_REQ_INFO",
- "CONF_PEER_INFO",
- "CONF_REQ_SLAVES",
- "CONF_SLAVES_INFO",
- "CONF_PEERS_REMOVED"
- ]
-
- def __sendDatagramPacket(self, subnet, size, addr, port):
- try:
- if addr is None:
- addr = subnet.broadcast
- port = DISCOVEY_PORT
- for slave in self.slaves:
- self.__sendDatagramPacket(subnet, size, slave.address, slave.port)
- if not subnet.contains(addr): return False
- if port == self.socket.getsockname()[1] and addr == subnet.address: return False
- self.socket.sendto(str(self.out_buf[:size]), (addr.getHostAddress(), port))
-
- if __TRACE_DISCOVERY__:
- map = None
- if self.out_buf[4] == locator.CONF_PEER_INFO:
- map = self.__parsePeerAttributes(self.out_buf, 8)
- elif self.out_buf[4] == locator.CONF_SLAVES_INFO:
- map = self.__parseIDs(self.out_buf, size)
- elif self.out_buf[4] == locator.CONF_PEERS_REMOVED:
- map = self.__parseIDs(self.out_buf, size)
- self.__traceDiscoveryPacket(False, self.packetTypes[self.out_buf[4]], map, addr, port)
- except Exception as x:
- self._log("Cannot send datagram packet to %s" % addr, x)
- return False
- return True
-
- def __parsePeerAttributes(self, data, size):
- """
- Parse peer attributes in CONF_PEER_INFO packet data
-
- @param data - the packet data
- @param size - the packet size
- @return a map containing the attributes
- """
- map = {}
- s = data[8:size - 8].decode("UTF-8")
- l = len(s)
- i = 0
- while i < l:
- i0 = i
- while i < l and s[i] != '=' and s[i] != '\0': i += 1
- i1 = i
- if i < l and s[i] == '=': i += 1
- i2 = i
- while i < l and s[i] != '\0': i += 1
- i3 = i
- if i < l and s[i] == '\0': i += 1
- key = s[i0:i1]
- val = s[i2:i3]
- map[key] = val
- return map
-
- def __parseIDs(self, data, size):
- """
- Parse list of IDs in CONF_SLAVES_INFO and CONF_PEERS_REMOVED packet data.
-
- @param data - the packet data
- @param size - the packet size
- @return a map containing the IDs
- """
- cnt = 0
- map = {}
- s = data[8:size - 8].decode("UTF-8")
- l = len(s)
- i = 0
- while i < l:
- i0 = i
- while i < l and s[i] != '\0': i += 1
- if i > i0:
- id = s[i0:i]
- map[str(cnt)] = id
- cnt += 1
- while i < l and s[i] == '\0': i += 1
- return map
-
- def __sendPeersRequest(self, addr, port):
- self.out_buf[4] = locator.CONF_REQ_INFO
- for subnet in self.subnets:
- self.__sendDatagramPacket(subnet, 8, addr, port)
-
- def _sendPeerInfo(self, _peer, addr, port):
- attrs = _peer.getAttributes()
- peer_addr = self.__getInetAddress(attrs.get(peer.ATTR_IP_HOST))
- if peer_addr is None: return
- if attrs.get(peer.ATTR_IP_PORT) is None: return
- self.out_buf[4] = locator.CONF_PEER_INFO
- i = 8
-
- for subnet in self.subnets:
- if isinstance(_peer, peer.RemotePeer):
- if self.socket.getsockname()[1] != DISCOVEY_PORT: return
- if not subnet.address == self.loopback_addr and not subnet.address == peer_addr: continue
- if not subnet.address == self.loopback_addr:
- if not subnet.contains(peer_addr): continue
- if i == 8:
- sb = cStringIO.StringIO()
- for key in attrs.keys():
- sb.write(key)
- sb.write('=')
- sb.write(attrs.get(key))
- sb.write('\0')
- bt = self.__getUTF8Bytes(sb.getvalue())
- if i + len(bt) > len(self.out_buf): return
- self.out_buf[i:i+len(bt)] = bt
- i += len(bt)
- if self.__sendDatagramPacket(subnet, i, addr, port): subnet.send_all_ok = True
-
- def __sendEmptyPacket(self, addr, port):
- self.out_buf[4] = locator.CONF_SLAVES_INFO
- for subnet in self.subnets:
- if subnet.send_all_ok: continue
- self.__sendDatagramPacket(subnet, 8, addr, port)
-
- def __sendAll(self, addr, port, sl, tm):
- for subnet in self.subnets: subnet.send_all_ok = False
- for peer in self.peers.values(): self._sendPeerInfo(peer, addr, port)
- if addr is not None and sl is not None and sl.last_req_slaves_time + locator.DATA_RETENTION_PERIOD >= tm:
- self.__sendSlavesInfo(addr, port, tm)
- self.__sendEmptyPacket(addr, port)
-
- def __sendSlavesRequest(self, subnet, addr, port):
- self.out_buf[4] = locator.CONF_REQ_SLAVES
- self.__sendDatagramPacket(subnet, 8, addr, port)
-
- def __sendSlaveInfo(self, x, tm):
- ttl = x.last_packet_time + locator.DATA_RETENTION_PERIOD - tm
- if ttl <= 0: return
- self.out_buf[4] = locator.CONF_SLAVES_INFO
- for subnet in self.subnets:
- if not subnet.contains(x.address): continue
- i = 8
- s = "%d:%s:%s" % (ttl, x.port, x.address.getHostAddress())
- bt = self.__getUTF8Bytes(s)
- self.out_buf[i:i+len(bt)] = bt
- i += len(bt)
- self.out_buf[i] = 0
- i += 1
- for y in self.slaves:
- if not subnet.contains(y.address): continue
- if y.last_req_slaves_time + locator.DATA_RETENTION_PERIOD < tm: continue
- self.__sendDatagramPacket(subnet, i, y.address, y.port)
-
- def __sendSlavesInfo(self, addr, port, tm):
- self.out_buf[4] = locator.CONF_SLAVES_INFO
- for subnet in self.subnets:
- if not subnet.contains(addr): continue
- i = 8
- for x in self.slaves:
- ttl = x.last_packet_time + locator.DATA_RETENTION_PERIOD - tm
- if ttl <= 0: return
- if x.port == port and x.address == addr: continue
- if not subnet.address == self.loopback_addr:
- if not subnet.contains(x.address): continue
- subnet.send_all_ok = True
- s = "%d:%s:%s" % (x.last_packet_time, x.port, x.address.getHostAddress())
- bt = self.__getUTF8Bytes(s)
- if i > 8 and i + len(bt) >= PREF_PACKET_SIZE:
- self.__sendDatagramPacket(subnet, i, addr, port)
- i = 8
- self.out_buf[i:len(bt)] = bt
- i += len(bt)
- self.out_buf[i] = 0
- i += 1
- if i > 8: self.__sendDatagramPacket(subnet, i, addr, port)
-
- def __isRemote(self, address, port):
- if port != self.socket.getsockname()[1]: return True
- for s in self.subnets:
- if s.address == address: return False
- return True
-
- def __handleDatagramPacket(self, p):
- try:
- tm = int(time.time() * 1000)
- buf = p.getData()
- len = p.getLength()
- if len < 8: return
- if buf[0] != 'T': return
- if buf[1] != 'C': return
- if buf[2] != 'F': return
- if buf[3] != locator.CONF_VERSION: return
- remote_port = p.getPort()
- remote_address = p.getAddress()
- if self.__isRemote(remote_address, remote_port):
- if buf[4] == locator.CONF_PEERS_REMOVED:
- self.__handlePeerRemovedPacket(p)
- else:
- sl = None
- if remote_port != DISCOVEY_PORT:
- sl = self.__addSlave(remote_address, remote_port, tm, tm)
- code = ord(buf[4])
- if code == locator.CONF_PEER_INFO:
- self.__handlePeerInfoPacket(p)
- elif code == locator.CONF_REQ_INFO:
- self.__handleReqInfoPacket(p, sl, tm)
- elif code == locator.CONF_SLAVES_INFO:
- self.__handleSlavesInfoPacket(p, tm)
- elif code == locator.CONF_REQ_SLAVES:
- self.__handleReqSlavesPacket(p, sl, tm)
- for subnet in self.subnets:
- if not subnet.contains(remote_address): continue
- delay = locator.DATA_RETENTION_PERIOD / 3
- if remote_port != DISCOVEY_PORT: delay = locator.DATA_RETENTION_PERIOD / 32
- elif subnet.address != remote_address: delay = locator.DATA_RETENTION_PERIOD / 2
- if subnet.last_slaves_req_time + delay <= tm:
- self.__sendSlavesRequest(subnet, remote_address, remote_port)
- subnet.last_slaves_req_time = tm
- if subnet.address == remote_address and remote_port == DISCOVEY_PORT:
- self.last_master_packet_time = tm
- except Exception as x:
- self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
-
- def __handlePeerInfoPacket(self, p):
- try:
- map = self.__parsePeerAttributes(p.getData(), p.getLength())
- if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_PEER_INFO", map, p)
- id = map.get(peer.ATTR_ID)
- if id is None: raise RuntimeError("Invalid peer info: no ID")
- ok = True
- host = map.get(peer.ATTR_IP_HOST)
- if host is not None:
- ok = False
- peer_addr = self.__getInetAddress(host)
- if peer_addr is not None:
- for subnet in self.subnets:
- if subnet.contains(peer_addr):
- ok = True
- break
- if ok:
- _peer = self.peers.get(id)
- if isinstance(_peer, peer.RemotePeer):
- _peer.updateAttributes(map)
- elif _peer is None:
- peer.RemotePeer(map)
- except Exception as x:
- self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
-
- def __handleReqInfoPacket(self, p, sl, tm):
- if __TRACE_DISCOVERY__:
- self.__traceDiscoveryPacket(True, "CONF_REQ_INFO", None, p)
- self.__sendAll(p.getAddress(), p.getPort(), sl, tm)
-
- def __handleSlavesInfoPacket(self, p, time_now):
- try:
- map = self.__parseIDs(p.getData(), p.getLength())
- if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_SLAVES_INFO", map, p)
- for s in map.values():
- i = 0
- l = len(s)
- time0 = i
- while i < l and s[i] != ':' and s[i] != '\0': i += 1
- time1 = i
- if i < l and s[i] == ':': i += 1
- port0 = i
- while i < l and s[i] != ':' and s[i] != '\0': i += 1
- port1 = i
- if i < l and s[i] == ':': i += 1
- host0 = i
- while i < l and s[i] != '\0': i += 1
- host1 = i
- port = int(s[port0:port1])
- timestamp = s[time0:time1]
- host = s[host0:host1]
- if port != DISCOVEY_PORT:
- addr = self.__getInetAddress(host)
- if addr is not None:
- delta = 10006030 # 30 minutes
- if len(timestamp) > 0:
- time_val = int(timestamp)
- else:
- time_val = time_now
- if time_val < 3600000:
- # Time stamp is "time to live" in milliseconds
- time_val = time_now + time_val / 1000 - locator.DATA_RETENTION_PERIOD
- elif time_val < time_now / 1000 + 50000000:
- # Time stamp is in seconds
- time_val= 1000
- else:
- # Time stamp is in milliseconds
- pass
- if time_val < time_now - delta or time_val > time_now + delta:
- msg = "Invalid slave info timestamp: %s -> %s" % (
- timestamp, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time_val/1000.)))
- self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), Exception(msg))
- time_val = time_now - locator.DATA_RETENTION_PERIOD / 2
- self.__addSlave(addr, port, time_val, time_now)
- except Exception as x:
- self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
-
- def __handleReqSlavesPacket(self, p, sl, tm):
- if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_REQ_SLAVES", None, p)
- if sl is not None: sl.last_req_slaves_time = tm
- self.__sendSlavesInfo(p.getAddress(), p.getPort(), tm)
-
- def __handlePeerRemovedPacket(self, p):
- try:
- map = self.__parseIDs(p.getData(), p.getLength())
- if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_PEERS_REMOVED", map, p)
- for id in map.values():
- _peer = self.peers.get(id)
- if isinstance(_peer, peer.RemotePeer): _peer.dispose()
- except Exception as x:
- self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
-
-
- @classmethod
- def getLocator(cls):
- return cls.locator
-
- def getPeers(self):
- assert protocol.isDispatchThread()
- return self.peers
-
- def redirect(self, peer, done):
- raise RuntimeError("Channel redirect cannot be done on local peer")
-
- def sync(self, done):
- raise RuntimeError("Channel sync cannot be done on local peer")
-
- def addListener(self, listener):
- assert listener is not None
- assert protocol.isDispatchThread()
- self.listeners.append(listener)
-
- def removeListener(self, listener):
- assert protocol.isDispatchThread()
- self.listeners.remove(listener)
-
- @classmethod
- def __traceDiscoveryPacket(cls, received, type, attrs, addr, port=None):
- """
- Log that a TCF Discovery packet has be sent or received. The trace is
- sent to stdout. This should be called only if the tracing has been turned
- on.
-
- @param received
- True if the packet was sent, otherwise it was received
- @param type
- a string specifying the type of packet, e.g., "CONF_PEER_INFO"
- @param attrs
- a set of attributes relevant to the type of packet (typically
- a peer's attributes)
- @param addr
- the network address the packet is being sent to
- @param port
- the port the packet is being sent to
- """
- assert __TRACE_DISCOVERY__
- if port is None:
- # addr is a InputPacket
- port = addr.getPort()
- addr = addr.getAddress()
- str = cStringIO.StringIO()
- str.write(type)
- str.write((" sent to ", " received from ")[received])
- str.write("%s/%s" % (addr, port))
- if attrs is not None:
- for key, value in attrs.items():
- str.write("\n\t%s=%s" % (key, value))
- logging.trace(str.getvalue())
-
-class LocatorServiceProvider(services.ServiceProvider):
- def getLocalService(self, _channel):
- class CommandServer(channel.CommandServer):
- def command(self, token, name, data):
- LocatorService.locator.command(channel, token, name, data)
- _channel.addCommandServer(LocatorService.locator, CommandServer())
- return (LocatorService.locator,)
-
-services.addServiceProvider(LocatorServiceProvider())
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Locator service uses transport layer to search
+for peers and to collect and maintain up-to-date
+data about peer's attributes.
+"""
+
+import threading, time, socket, cStringIO
+from tcf.services import locator
+from tcf.util import logging
+from tcf.channel import fromJSONSequence, toJSONSequence
+from tcf.channel.ChannelProxy import ChannelProxy
+from tcf import protocol, services, channel, peer, errors
+
+# Flag indicating whether tracing of the the discovery activity is enabled.
+__TRACE_DISCOVERY__ = False
+
+class SubNet(object):
+ def __init__(self, prefix_length, address, broadcast):
+ self.prefix_length = prefix_length
+ self.address = address
+ self.broadcast = broadcast
+ self.last_slaves_req_time = 0
+ def contains(self, addr):
+ if addr is None or self.address is None: return False
+ a1 = addr.getAddress()
+ a2 = self.address.getAddress()
+ if len(a1) != len(a2): return False
+ i = 0
+ if self.prefix_length <= len(a1) * 8:
+ l = self.prefix_length
+ else:
+ l = len(a1) * 8
+ while i + 8 <= l:
+ n = i / 8
+ if a1[n] != a2[n]: return False
+ i += 8
+ while i < l:
+ n = i / 8
+ m = 1 << (7 - i % 8)
+ if (a1[n] & m) != (a2[n] & m): return False
+ i += 1
+ return True
+ def __eq__(self, o):
+ if not isinstance(o, SubNet): return False
+ return self.prefix_length == o.prefix_length and \
+ self.broadcast == o.broadcast and \
+ self.address == o.address
+ def __hash__(self):
+ return hash(self.address)
+ def __str__(self):
+ return "%s/%d" % (self.address.getHostAddress(), self.prefix_length)
+
+class Slave(object):
+ # Time of last packet receiver from self slave
+ last_packet_time = 0
+ #Time of last REQ_SLAVES packet received from self slave
+ last_req_slaves_time = 0
+
+ def __init__(self, address, port):
+ self.address = address
+ self.port = port
+ def __str__(self):
+ return "%s/%d" % (self.address.getHostAddress(), self.port)
+
+class AddressCacheItem(object):
+ address = None
+ time_stamp = 0
+ used = False
+ def __init__(self, host):
+ self.host = host
+
+class InetAddress(object):
+ "Mimicking Java InetAddress class"
+ def __init__(self, host, addr):
+ self.host = host
+ self.addr = addr
+ def getAddress(self):
+ return socket.inet_aton(self.addr)
+ def getHostAddress(self):
+ return self.addr
+ def __eq__(self, other):
+ if not isinstance(other, InetAddress): return False
+ return self.addr == other.addr
+ def __str__(self):
+ return "%s/%s" % (self.host or "", self.addr)
+
+class InputPacket(object):
+ "Wrapper for UDP packet data."
+ def __init__(self, data, addr, port):
+ self.data = data
+ self.addr = addr
+ self.port = port
+ def getLength(self):
+ return len(self.data)
+ def getData(self):
+ return self.data
+ def getPort(self):
+ return self.port
+ def getAddress(self):
+ return self.addr
+ def __str__(self):
+ return "[address=%s,port=%d,data=\"%s\"]" % (self.getAddress(), self.getPort(), self.data)
+
+DISCOVEY_PORT = 1534
+MAX_PACKET_SIZE = 9000 - 40 - 8
+PREF_PACKET_SIZE = 1500 - 40 - 8
+
+# TODO: research usage of DNS-SD (DNS Service Discovery) to discover TCF peers
+class LocatorService(locator.LocatorService):
+ locator = None
+ peers = {} # str->Peer
+ listeners = [] # list of LocatorListener
+ error_log = set() # set of str
+
+ addr_cache = {} # str->AddressCacheItem
+ addr_request = False
+ local_peer = None
+ last_master_packet_time = 0
+
+ @classmethod
+ def getLocalPeer(cls):
+ return cls.local_peer
+
+ @classmethod
+ def getListeners(cls):
+ return cls.listeners[:]
+
+ @classmethod
+ def startup(cls):
+ if cls.locator:
+ cls.locator._startup()
+
+ @classmethod
+ def shutdown(cls):
+ if cls.locator:
+ cls.locator._shutdown()
+
+ def __init__(self):
+ self._error_log_lock = threading.RLock()
+ self._alive = False
+ LocatorService.locator = self
+ LocatorService.local_peer = peer.LocalPeer()
+
+ def _startup(self):
+ if self._alive: return
+ self._alive = True
+ self._addr_cache_lock = threading.Condition()
+ self.subnets = set()
+ self.slaves = []
+ self.inp_buf = bytearray(MAX_PACKET_SIZE)
+ self.out_buf = bytearray(MAX_PACKET_SIZE)
+ service = self
+ class TimerThread(threading.Thread):
+ def __init__(self, callable):
+ self._callable = callable
+ super(TimerThread, self).__init__()
+ def run(self):
+ while service._alive:
+ try:
+ time.sleep(locator.DATA_RETENTION_PERIOD / 4 / 1000.)
+ protocol.invokeAndWait(self._callable)
+ except RuntimeError:
+ # TCF event dispatch is shut down
+ return
+ except Exception as x:
+ service._log("Unhandled exception in TCF discovery timer thread", x)
+ self.timer_thread = TimerThread(self.__refresh_timer)
+ class DNSLookupThread(threading.Thread):
+ def run(self):
+ while service._alive:
+ try:
+ itemSet = None
+ with service._addr_cache_lock:
+ if not LocatorService.addr_request:
+ service._addr_cache_lock.wait(locator.DATA_RETENTION_PERIOD)
+ msec = int(time.time() * 1000)
+ for host, a in LocatorService.addr_cache.items():
+ if a.time_stamp + locator.DATA_RETENTION_PERIOD * 10 < msec:
+ if a.used:
+ if itemSet is None: itemSet = set()
+ itemSet.add(a)
+ else:
+ del LocatorService.addr_cache[host]
+ LocatorService.addr_request = False
+ if itemSet is not None:
+ for a in itemSet:
+ addr = None
+ try:
+ addr = socket.gethostbyname(a.host)
+ except socket.gaierror:
+ pass
+ with service._addr_cache_lock:
+ if addr is None:
+ a.address = None
+ else:
+ a.address = InetAddress(a.host, addr)
+ a.time_stamp = msec
+ a.used = False
+ except Exception as x:
+ service._log("Unhandled exception in TCF discovery DNS lookup thread", x)
+ self.dns_lookup_thread = DNSLookupThread()
+ class InputThread(threading.Thread):
+ def __init__(self, callable):
+ self._callable = callable
+ super(InputThread, self).__init__()
+ def run(self):
+ try:
+ while service._alive:
+ sock = service.socket
+ try:
+ data, addr = sock.recvfrom(MAX_PACKET_SIZE)
+ p = InputPacket(data, InetAddress(None, addr[0]), addr[1])
+ protocol.invokeAndWait(self._callable, p)
+ except RuntimeError:
+ # TCF event dispatch is shutdown
+ return
+ except socket.error as x:
+ if sock != service.socket: continue
+ # frequent error on windows, unknown reason
+ if x.errno == 10054: continue
+ port = sock.getsockname()[1]
+ service._log("Cannot read from datagram socket at port %d" % port, x)
+ time.sleep(2)
+ except Exception as x:
+ service._log("Unhandled exception in socket reading thread", x)
+ self.input_thread = InputThread(self.__handleDatagramPacket)
+ try:
+ self.loopback_addr = InetAddress(None, "127.0.0.1")
+ self.out_buf[0:8] = 'TCF%s\0\0\0\0' % locator.CONF_VERSION
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ try:
+ self.socket.bind(('', DISCOVEY_PORT))
+ if __TRACE_DISCOVERY__:
+ logging.trace("Became the master agent (bound to port %d)" % self.socket.getsockname()[1])
+ except socket.error as x:
+ self.socket.bind(('', 0))
+ if __TRACE_DISCOVERY__:
+ logging.trace("Became a slave agent (bound to port %d)" % self.socket.getsockname()[1])
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+ self.input_thread.setName("TCF Locator Receiver")
+ self.timer_thread.setName("TCF Locator Timer")
+ self.dns_lookup_thread.setName("TCF Locator DNS Lookup")
+ self.input_thread.setDaemon(True)
+ self.timer_thread.setDaemon(True)
+ self.dns_lookup_thread.setDaemon(True)
+ self.input_thread.start()
+ self.timer_thread.start()
+ self.dns_lookup_thread.start()
+ class LocatorListener(locator.LocatorListener):
+ def peerAdded(self, peer):
+ service._sendPeerInfo(peer, None, 0)
+ def peerChanged(self, peer):
+ service._sendPeerInfo(peer, None, 0)
+ self.listeners.append(LocatorListener())
+ self.__refreshSubNetList()
+ self.__sendPeersRequest(None, 0)
+ self.__sendAll(None, 0, None, int(time.time() * 1000))
+ except Exception as x:
+ self._log("Cannot open UDP socket for TCF discovery protocol", x)
+
+ def _shutdown(self):
+ if self._alive:
+ self._alive = False
+
+ def __makeErrorReport(self, code, msg):
+ err = {}
+ err[errors.ERROR_TIME] = int(time.time() * 1000)
+ err[errors.ERROR_CODE] = code
+ err[errors.ERROR_FORMAT] = msg
+ return err
+
+ def __command(self, channel, token, name, data):
+ try:
+ if name == "redirect":
+ peer_id = fromJSONSequence(data)[0]
+ _peer = self.peers.get(peer_id)
+ if _peer is None:
+ error = self.__makeErrorReport(errors.TCF_ERROR_UNKNOWN_PEER, "Unknown peer ID")
+ channel.sendResult(token, toJSONSequence((error,)))
+ return
+ channel.sendResult(token, toJSONSequence((None,)))
+ if isinstance(_peer, peer.LocalPeer):
+ channel.sendEvent(protocol.getLocator(), "Hello", toJSONSequence((channel.getLocalServices(),)))
+ return
+ ChannelProxy(channel, _peer.openChannel())
+ elif name == "sync":
+ channel.sendResult(token, None)
+ elif name == "getPeers":
+ arr = []
+ for p in self.peers.values():
+ arr.append(p.getAttributes())
+ channel.sendResult(token, toJSONSequence((None, arr)))
+ else:
+ channel.rejectCommand(token)
+ except Exception as x:
+ channel.terminate(x)
+
+ def _log(self, msg, x):
+ if not self._alive: return
+ # Don't report same error multiple times to avoid filling up the log file.
+ with self._error_log_lock:
+ if msg in self.error_log: return
+ self.error_log.add(msg)
+ protocol.log(msg, x)
+
+ def __getInetAddress(self, host):
+ if not host: return None
+ with self._addr_cache_lock:
+ i = self.addr_cache.get(host)
+ if i is None:
+ i = AddressCacheItem(host)
+ ch = host[0]
+ if ch == '[' or ch == ':' or ch >= '0' and ch <= '9':
+ try:
+ addr = socket.gethostbyname(host)
+ i.address = InetAddress(host, addr)
+ except socket.gaierror:
+ pass
+ i.time_stamp = int(time.time() * 1000)
+ else:
+ # socket.gethostbyname() can cause long delay - delegate to background thread
+ LocatorService.addr_request = True
+ self._addr_cache_lock.notify()
+ self.addr_cache[host] = i
+ i.used = True
+ return i.address
+
+ def __refresh_timer(self):
+ tm = int(time.time() * 1000)
+ # Cleanup slave table
+ if self.slaves:
+ i = 0
+ while i < len(self.slaves):
+ s = self.slaves[i]
+ if s.last_packet_time + locator.DATA_RETENTION_PERIOD < tm:
+ del self.slaves[i]
+ else:
+ i += 1
+
+ # Cleanup peers table
+ stale_peers = None
+ for p in self.peers.values():
+ if isinstance(p, peer.RemotePeer):
+ if p.getLastUpdateTime() + locator.DATA_RETENTION_PERIOD < tm:
+ if stale_peers == None: stale_peers = []
+ stale_peers.append(p)
+ if stale_peers is not None:
+ for p in stale_peers: p.dispose()
+
+ # Try to become a master
+ port = self.socket.getsockname()[1]
+ if port != DISCOVEY_PORT and \
+ self.last_master_packet_time + locator.DATA_RETENTION_PERIOD / 2 <= tm:
+ s0 = self.socket
+ s1 = None
+ try:
+ s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s1.bind(DISCOVEY_PORT)
+ s1.setsockopt(socket.SOL_UDP, socket.SO_BROADCAST, 1)
+ self.socket = s1
+ s0.close()
+ except:
+ pass
+ self.__refreshSubNetList()
+ if port != DISCOVEY_PORT:
+ for subnet in self.subnets:
+ self.__addSlave(subnet.address, port, tm, tm)
+ self.__sendAll(None, 0, None, tm)
+
+ def __addSlave(self, addr, port, timestamp, time_now):
+ for s in self.slaves:
+ if s.port == port and s.address == addr:
+ if s.last_packet_time < timestamp: s.last_packet_time = timestamp
+ return s
+ s = Slave(addr, port)
+ s.last_packet_time = timestamp
+ self.slaves.append(s)
+ self.__sendPeersRequest(addr, port)
+ self.__sendAll(addr, port, s, time_now)
+ self.__sendSlaveInfo(s, time_now)
+ return s
+
+ def __refreshSubNetList(self):
+ subNetSet = set()
+ try:
+ self.__getSubNetList(subNetSet)
+ except Exception as x:
+ self._log("Cannot get list of network interfaces", x)
+ for s in tuple(self.subnets):
+ if s in subNetSet: continue
+ self.subnets.remove(s)
+ for s in subNetSet:
+ if s in self.subnets: continue
+ self.subnets.add(s)
+ if __TRACE_DISCOVERY__:
+ str = cStringIO.StringIO()
+ str.write("Refreshed subnet list:")
+ for subnet in self.subnets:
+ str.write("\n\t* address=%s, broadcast=%s" % (subnet.address, subnet.broadcast))
+ logging.trace(str.getvalue())
+
+ def __getSubNetList(self, set):
+ # TODO iterate over network interfaces to get proper broadcast addresses
+ hostname = socket.gethostname()
+ _, _, addresses = socket.gethostbyname_ex(hostname)
+ if not "127.0.0.1" in addresses:
+ addresses.append("127.0.0.1")
+ for address in addresses:
+ rawaddr = socket.inet_aton(address)
+ if len(rawaddr) != 4: continue
+ rawaddr = rawaddr[:3] + '\xFF'
+ broadcast = socket.inet_ntoa(rawaddr)
+ set.add(SubNet(24, InetAddress(hostname, address), InetAddress(None, broadcast)))
+
+ def __getUTF8Bytes(self, s):
+ return s.encode("UTF-8")
+
+ # Used for tracing
+ packetTypes = [
+ None,
+ "CONF_REQ_INFO",
+ "CONF_PEER_INFO",
+ "CONF_REQ_SLAVES",
+ "CONF_SLAVES_INFO",
+ "CONF_PEERS_REMOVED"
+ ]
+
+ def __sendDatagramPacket(self, subnet, size, addr, port):
+ try:
+ if addr is None:
+ addr = subnet.broadcast
+ port = DISCOVEY_PORT
+ for slave in self.slaves:
+ self.__sendDatagramPacket(subnet, size, slave.address, slave.port)
+ if not subnet.contains(addr): return False
+ if port == self.socket.getsockname()[1] and addr == subnet.address: return False
+ self.socket.sendto(str(self.out_buf[:size]), (addr.getHostAddress(), port))
+
+ if __TRACE_DISCOVERY__:
+ map = None
+ if self.out_buf[4] == locator.CONF_PEER_INFO:
+ map = self.__parsePeerAttributes(self.out_buf, 8)
+ elif self.out_buf[4] == locator.CONF_SLAVES_INFO:
+ map = self.__parseIDs(self.out_buf, size)
+ elif self.out_buf[4] == locator.CONF_PEERS_REMOVED:
+ map = self.__parseIDs(self.out_buf, size)
+ self.__traceDiscoveryPacket(False, self.packetTypes[self.out_buf[4]], map, addr, port)
+ except Exception as x:
+ self._log("Cannot send datagram packet to %s" % addr, x)
+ return False
+ return True
+
+ def __parsePeerAttributes(self, data, size):
+ """
+ Parse peer attributes in CONF_PEER_INFO packet data
+
+ @param data - the packet data
+ @param size - the packet size
+ @return a map containing the attributes
+ """
+ map = {}
+ s = data[8:size - 8].decode("UTF-8")
+ l = len(s)
+ i = 0
+ while i < l:
+ i0 = i
+ while i < l and s[i] != '=' and s[i] != '\0': i += 1
+ i1 = i
+ if i < l and s[i] == '=': i += 1
+ i2 = i
+ while i < l and s[i] != '\0': i += 1
+ i3 = i
+ if i < l and s[i] == '\0': i += 1
+ key = s[i0:i1]
+ val = s[i2:i3]
+ map[key] = val
+ return map
+
+ def __parseIDs(self, data, size):
+ """
+ Parse list of IDs in CONF_SLAVES_INFO and CONF_PEERS_REMOVED packet data.
+
+ @param data - the packet data
+ @param size - the packet size
+ @return a map containing the IDs
+ """
+ cnt = 0
+ map = {}
+ s = data[8:size - 8].decode("UTF-8")
+ l = len(s)
+ i = 0
+ while i < l:
+ i0 = i
+ while i < l and s[i] != '\0': i += 1
+ if i > i0:
+ id = s[i0:i]
+ map[str(cnt)] = id
+ cnt += 1
+ while i < l and s[i] == '\0': i += 1
+ return map
+
+ def __sendPeersRequest(self, addr, port):
+ self.out_buf[4] = locator.CONF_REQ_INFO
+ for subnet in self.subnets:
+ self.__sendDatagramPacket(subnet, 8, addr, port)
+
+ def _sendPeerInfo(self, _peer, addr, port):
+ attrs = _peer.getAttributes()
+ peer_addr = self.__getInetAddress(attrs.get(peer.ATTR_IP_HOST))
+ if peer_addr is None: return
+ if attrs.get(peer.ATTR_IP_PORT) is None: return
+ self.out_buf[4] = locator.CONF_PEER_INFO
+ i = 8
+
+ for subnet in self.subnets:
+ if isinstance(_peer, peer.RemotePeer):
+ if self.socket.getsockname()[1] != DISCOVEY_PORT: return
+ if not subnet.address == self.loopback_addr and not subnet.address == peer_addr: continue
+ if not subnet.address == self.loopback_addr:
+ if not subnet.contains(peer_addr): continue
+ if i == 8:
+ sb = cStringIO.StringIO()
+ for key in attrs.keys():
+ sb.write(key)
+ sb.write('=')
+ sb.write(attrs.get(key))
+ sb.write('\0')
+ bt = self.__getUTF8Bytes(sb.getvalue())
+ if i + len(bt) > len(self.out_buf): return
+ self.out_buf[i:i+len(bt)] = bt
+ i += len(bt)
+ if self.__sendDatagramPacket(subnet, i, addr, port): subnet.send_all_ok = True
+
+ def __sendEmptyPacket(self, addr, port):
+ self.out_buf[4] = locator.CONF_SLAVES_INFO
+ for subnet in self.subnets:
+ if subnet.send_all_ok: continue
+ self.__sendDatagramPacket(subnet, 8, addr, port)
+
+ def __sendAll(self, addr, port, sl, tm):
+ for subnet in self.subnets: subnet.send_all_ok = False
+ for peer in self.peers.values(): self._sendPeerInfo(peer, addr, port)
+ if addr is not None and sl is not None and sl.last_req_slaves_time + locator.DATA_RETENTION_PERIOD >= tm:
+ self.__sendSlavesInfo(addr, port, tm)
+ self.__sendEmptyPacket(addr, port)
+
+ def __sendSlavesRequest(self, subnet, addr, port):
+ self.out_buf[4] = locator.CONF_REQ_SLAVES
+ self.__sendDatagramPacket(subnet, 8, addr, port)
+
+ def __sendSlaveInfo(self, x, tm):
+ ttl = x.last_packet_time + locator.DATA_RETENTION_PERIOD - tm
+ if ttl <= 0: return
+ self.out_buf[4] = locator.CONF_SLAVES_INFO
+ for subnet in self.subnets:
+ if not subnet.contains(x.address): continue
+ i = 8
+ s = "%d:%s:%s" % (ttl, x.port, x.address.getHostAddress())
+ bt = self.__getUTF8Bytes(s)
+ self.out_buf[i:i+len(bt)] = bt
+ i += len(bt)
+ self.out_buf[i] = 0
+ i += 1
+ for y in self.slaves:
+ if not subnet.contains(y.address): continue
+ if y.last_req_slaves_time + locator.DATA_RETENTION_PERIOD < tm: continue
+ self.__sendDatagramPacket(subnet, i, y.address, y.port)
+
+ def __sendSlavesInfo(self, addr, port, tm):
+ self.out_buf[4] = locator.CONF_SLAVES_INFO
+ for subnet in self.subnets:
+ if not subnet.contains(addr): continue
+ i = 8
+ for x in self.slaves:
+ ttl = x.last_packet_time + locator.DATA_RETENTION_PERIOD - tm
+ if ttl <= 0: return
+ if x.port == port and x.address == addr: continue
+ if not subnet.address == self.loopback_addr:
+ if not subnet.contains(x.address): continue
+ subnet.send_all_ok = True
+ s = "%d:%s:%s" % (x.last_packet_time, x.port, x.address.getHostAddress())
+ bt = self.__getUTF8Bytes(s)
+ if i > 8 and i + len(bt) >= PREF_PACKET_SIZE:
+ self.__sendDatagramPacket(subnet, i, addr, port)
+ i = 8
+ self.out_buf[i:len(bt)] = bt
+ i += len(bt)
+ self.out_buf[i] = 0
+ i += 1
+ if i > 8: self.__sendDatagramPacket(subnet, i, addr, port)
+
+ def __isRemote(self, address, port):
+ if port != self.socket.getsockname()[1]: return True
+ for s in self.subnets:
+ if s.address == address: return False
+ return True
+
+ def __handleDatagramPacket(self, p):
+ try:
+ tm = int(time.time() * 1000)
+ buf = p.getData()
+ len = p.getLength()
+ if len < 8: return
+ if buf[0] != 'T': return
+ if buf[1] != 'C': return
+ if buf[2] != 'F': return
+ if buf[3] != locator.CONF_VERSION: return
+ remote_port = p.getPort()
+ remote_address = p.getAddress()
+ if self.__isRemote(remote_address, remote_port):
+ if buf[4] == locator.CONF_PEERS_REMOVED:
+ self.__handlePeerRemovedPacket(p)
+ else:
+ sl = None
+ if remote_port != DISCOVEY_PORT:
+ sl = self.__addSlave(remote_address, remote_port, tm, tm)
+ code = ord(buf[4])
+ if code == locator.CONF_PEER_INFO:
+ self.__handlePeerInfoPacket(p)
+ elif code == locator.CONF_REQ_INFO:
+ self.__handleReqInfoPacket(p, sl, tm)
+ elif code == locator.CONF_SLAVES_INFO:
+ self.__handleSlavesInfoPacket(p, tm)
+ elif code == locator.CONF_REQ_SLAVES:
+ self.__handleReqSlavesPacket(p, sl, tm)
+ for subnet in self.subnets:
+ if not subnet.contains(remote_address): continue
+ delay = locator.DATA_RETENTION_PERIOD / 3
+ if remote_port != DISCOVEY_PORT: delay = locator.DATA_RETENTION_PERIOD / 32
+ elif subnet.address != remote_address: delay = locator.DATA_RETENTION_PERIOD / 2
+ if subnet.last_slaves_req_time + delay <= tm:
+ self.__sendSlavesRequest(subnet, remote_address, remote_port)
+ subnet.last_slaves_req_time = tm
+ if subnet.address == remote_address and remote_port == DISCOVEY_PORT:
+ self.last_master_packet_time = tm
+ except Exception as x:
+ self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
+
+ def __handlePeerInfoPacket(self, p):
+ try:
+ map = self.__parsePeerAttributes(p.getData(), p.getLength())
+ if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_PEER_INFO", map, p)
+ id = map.get(peer.ATTR_ID)
+ if id is None: raise RuntimeError("Invalid peer info: no ID")
+ ok = True
+ host = map.get(peer.ATTR_IP_HOST)
+ if host is not None:
+ ok = False
+ peer_addr = self.__getInetAddress(host)
+ if peer_addr is not None:
+ for subnet in self.subnets:
+ if subnet.contains(peer_addr):
+ ok = True
+ break
+ if ok:
+ _peer = self.peers.get(id)
+ if isinstance(_peer, peer.RemotePeer):
+ _peer.updateAttributes(map)
+ elif _peer is None:
+ peer.RemotePeer(map)
+ except Exception as x:
+ self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
+
+ def __handleReqInfoPacket(self, p, sl, tm):
+ if __TRACE_DISCOVERY__:
+ self.__traceDiscoveryPacket(True, "CONF_REQ_INFO", None, p)
+ self.__sendAll(p.getAddress(), p.getPort(), sl, tm)
+
+ def __handleSlavesInfoPacket(self, p, time_now):
+ try:
+ map = self.__parseIDs(p.getData(), p.getLength())
+ if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_SLAVES_INFO", map, p)
+ for s in map.values():
+ i = 0
+ l = len(s)
+ time0 = i
+ while i < l and s[i] != ':' and s[i] != '\0': i += 1
+ time1 = i
+ if i < l and s[i] == ':': i += 1
+ port0 = i
+ while i < l and s[i] != ':' and s[i] != '\0': i += 1
+ port1 = i
+ if i < l and s[i] == ':': i += 1
+ host0 = i
+ while i < l and s[i] != '\0': i += 1
+ host1 = i
+ port = int(s[port0:port1])
+ timestamp = s[time0:time1]
+ host = s[host0:host1]
+ if port != DISCOVEY_PORT:
+ addr = self.__getInetAddress(host)
+ if addr is not None:
+ delta = 10006030 # 30 minutes
+ if len(timestamp) > 0:
+ time_val = int(timestamp)
+ else:
+ time_val = time_now
+ if time_val < 3600000:
+ # Time stamp is "time to live" in milliseconds
+ time_val = time_now + time_val / 1000 - locator.DATA_RETENTION_PERIOD
+ elif time_val < time_now / 1000 + 50000000:
+ # Time stamp is in seconds
+ time_val= 1000
+ else:
+ # Time stamp is in milliseconds
+ pass
+ if time_val < time_now - delta or time_val > time_now + delta:
+ msg = "Invalid slave info timestamp: %s -> %s" % (
+ timestamp, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time_val/1000.)))
+ self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), Exception(msg))
+ time_val = time_now - locator.DATA_RETENTION_PERIOD / 2
+ self.__addSlave(addr, port, time_val, time_now)
+ except Exception as x:
+ self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
+
+ def __handleReqSlavesPacket(self, p, sl, tm):
+ if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_REQ_SLAVES", None, p)
+ if sl is not None: sl.last_req_slaves_time = tm
+ self.__sendSlavesInfo(p.getAddress(), p.getPort(), tm)
+
+ def __handlePeerRemovedPacket(self, p):
+ try:
+ map = self.__parseIDs(p.getData(), p.getLength())
+ if __TRACE_DISCOVERY__: self.__traceDiscoveryPacket(True, "CONF_PEERS_REMOVED", map, p)
+ for id in map.values():
+ _peer = self.peers.get(id)
+ if isinstance(_peer, peer.RemotePeer): _peer.dispose()
+ except Exception as x:
+ self._log("Invalid datagram packet received from %s/%s" % (p.getAddress(), p.getPort()), x)
+
+
+ @classmethod
+ def getLocator(cls):
+ return cls.locator
+
+ def getPeers(self):
+ assert protocol.isDispatchThread()
+ return self.peers
+
+ def redirect(self, peer, done):
+ raise RuntimeError("Channel redirect cannot be done on local peer")
+
+ def sync(self, done):
+ raise RuntimeError("Channel sync cannot be done on local peer")
+
+ def addListener(self, listener):
+ assert listener is not None
+ assert protocol.isDispatchThread()
+ self.listeners.append(listener)
+
+ def removeListener(self, listener):
+ assert protocol.isDispatchThread()
+ self.listeners.remove(listener)
+
+ @classmethod
+ def __traceDiscoveryPacket(cls, received, type, attrs, addr, port=None):
+ """
+ Log that a TCF Discovery packet has be sent or received. The trace is
+ sent to stdout. This should be called only if the tracing has been turned
+ on.
+
+ @param received
+ True if the packet was sent, otherwise it was received
+ @param type
+ a string specifying the type of packet, e.g., "CONF_PEER_INFO"
+ @param attrs
+ a set of attributes relevant to the type of packet (typically
+ a peer's attributes)
+ @param addr
+ the network address the packet is being sent to
+ @param port
+ the port the packet is being sent to
+ """
+ assert __TRACE_DISCOVERY__
+ if port is None:
+ # addr is a InputPacket
+ port = addr.getPort()
+ addr = addr.getAddress()
+ str = cStringIO.StringIO()
+ str.write(type)
+ str.write((" sent to ", " received from ")[received])
+ str.write("%s/%s" % (addr, port))
+ if attrs is not None:
+ for key, value in attrs.items():
+ str.write("\n\t%s=%s" % (key, value))
+ logging.trace(str.getvalue())
+
+class LocatorServiceProvider(services.ServiceProvider):
+ def getLocalService(self, _channel):
+ class CommandServer(channel.CommandServer):
+ def command(self, token, name, data):
+ LocatorService.locator.command(channel, token, name, data)
+ _channel.addCommandServer(LocatorService.locator, CommandServer())
+ return (LocatorService.locator,)
+
+services.addServiceProvider(LocatorServiceProvider())
diff --git a/python/src/tcf/services/local/__init__.py b/python/src/tcf/services/local/__init__.py
index cf36110a7..29aa42bc1 100644
--- a/python/src/tcf/services/local/__init__.py
+++ b/python/src/tcf/services/local/__init__.py
@@ -1,10 +1,10 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
diff --git a/python/src/tcf/services/locator.py b/python/src/tcf/services/locator.py
index 10199a140..51006cba1 100644
--- a/python/src/tcf/services/locator.py
+++ b/python/src/tcf/services/locator.py
@@ -1,94 +1,94 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Locator service uses transport layer to search for peers and to collect data about
-peer's attributes and capabilities (services). Discovery mechanism depends on transport protocol
-and is part of that protocol handler. Targets, known to other hosts, can be found through
-remote instances of Locator service. Automatically discovered targets require no further
-configuration. Additional targets can be configured manually.
-
-Clients should use protocol.getLocator() to obtain local instance of locator,
-then locator.getPeers() can be used to get list of available peers (hosts and targets).
-"""
-
-from tcf import services
-
-# Peer data retention period in milliseconds.
-DATA_RETENTION_PERIOD = 60 * 1000;
-
-# Auto-configuration protocol version.
-CONF_VERSION = '2'
-
-# Auto-configuration command and response codes.
-CONF_REQ_INFO = 1
-CONF_PEER_INFO = 2
-CONF_REQ_SLAVES = 3
-CONF_SLAVES_INFO = 4
-CONF_PEERS_REMOVED = 5
-
-NAME = "Locator"
-
-class LocatorService(services.Service):
- def getName(self):
- return NAME
- def getPeers(self):
- """
- Get map (ID -> IPeer) of available peers (hosts and targets).
- The method return cached (currently known to the framework) list of peers.
- The list is updated according to event received from transport layer
- """
- raise NotImplementedError("Abstract method")
- def redirect(self, peer, done):
- """
- Redirect this service channel to given peer using this service as a proxy.
- @param peer - Peer ID or attributes map.
- """
- raise NotImplementedError("Abstract method")
- def sync(self, done):
- """
- Call back after TCF messages sent to this target up to this moment are delivered.
- This method is intended for synchronization of messages
- across multiple channels.
-
- Note: Cross channel synchronization can reduce performance and throughput.
- Most clients don't need channel synchronization and should not call this method.
-
- @param done will be executed by dispatch thread after communication
- messages are delivered to corresponding targets.
-
- This is internal API, TCF clients should use module 'tcf.protocol'.
- """
- raise NotImplementedError("Abstract method")
- def addListener(self, listener):
- "Add a listener for Locator service events."
- raise NotImplementedError("Abstract method")
- def removeListener(self, listener):
- "Remove a listener for Locator service events."
- raise NotImplementedError("Abstract method")
-
-class DoneRedirect(object):
- def doneRedirect(self, token, error):
- pass
-
-class DoneSync(object):
- def doneSync(self, token):
- pass
-
-class LocatorListener(object):
- def peerAdded(self, peer):
- pass
- def peerChanged(self, peer):
- pass
- def peerRemoved(self, id):
- pass
- def peerHeartBeat(self, id):
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Locator service uses transport layer to search for peers and to collect data about
+peer's attributes and capabilities (services). Discovery mechanism depends on transport protocol
+and is part of that protocol handler. Targets, known to other hosts, can be found through
+remote instances of Locator service. Automatically discovered targets require no further
+configuration. Additional targets can be configured manually.
+
+Clients should use protocol.getLocator() to obtain local instance of locator,
+then locator.getPeers() can be used to get list of available peers (hosts and targets).
+"""
+
+from tcf import services
+
+# Peer data retention period in milliseconds.
+DATA_RETENTION_PERIOD = 60 * 1000;
+
+# Auto-configuration protocol version.
+CONF_VERSION = '2'
+
+# Auto-configuration command and response codes.
+CONF_REQ_INFO = 1
+CONF_PEER_INFO = 2
+CONF_REQ_SLAVES = 3
+CONF_SLAVES_INFO = 4
+CONF_PEERS_REMOVED = 5
+
+NAME = "Locator"
+
+class LocatorService(services.Service):
+ def getName(self):
+ return NAME
+ def getPeers(self):
+ """
+ Get map (ID -> IPeer) of available peers (hosts and targets).
+ The method return cached (currently known to the framework) list of peers.
+ The list is updated according to event received from transport layer
+ """
+ raise NotImplementedError("Abstract method")
+ def redirect(self, peer, done):
+ """
+ Redirect this service channel to given peer using this service as a proxy.
+ @param peer - Peer ID or attributes map.
+ """
+ raise NotImplementedError("Abstract method")
+ def sync(self, done):
+ """
+ Call back after TCF messages sent to this target up to this moment are delivered.
+ This method is intended for synchronization of messages
+ across multiple channels.
+
+ Note: Cross channel synchronization can reduce performance and throughput.
+ Most clients don't need channel synchronization and should not call this method.
+
+ @param done will be executed by dispatch thread after communication
+ messages are delivered to corresponding targets.
+
+ This is internal API, TCF clients should use module 'tcf.protocol'.
+ """
+ raise NotImplementedError("Abstract method")
+ def addListener(self, listener):
+ "Add a listener for Locator service events."
+ raise NotImplementedError("Abstract method")
+ def removeListener(self, listener):
+ "Remove a listener for Locator service events."
+ raise NotImplementedError("Abstract method")
+
+class DoneRedirect(object):
+ def doneRedirect(self, token, error):
+ pass
+
+class DoneSync(object):
+ def doneSync(self, token):
+ pass
+
+class LocatorListener(object):
+ def peerAdded(self, peer):
+ pass
+ def peerChanged(self, peer):
+ pass
+ def peerRemoved(self, id):
+ pass
+ def peerHeartBeat(self, id):
+ pass
diff --git a/python/src/tcf/services/memory.py b/python/src/tcf/services/memory.py
index de97b2026..40a0c007a 100644
--- a/python/src/tcf/services/memory.py
+++ b/python/src/tcf/services/memory.py
@@ -1,303 +1,303 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Memory service provides basic operations to read/write memory on a target.
-"""
-
-from tcf import services
-
-NAME = "Memory"
-
-# Context property names.
-PROP_ID = "ID" # String, ID of the context, same as getContext command argument
-PROP_PARENT_ID = "ParentID" # String, ID of a parent context
-PROP_PROCESS_ID = "ProcessID" # String, process ID, see Processes service
-PROP_BIG_ENDIAN = "BigEndian" # Boolean, True if memory is big-endian
-PROP_ADDRESS_SIZE = "AddressSize" # Number, size of memory address in bytes
-PROP_NAME = "Name" # String, name of the context, can be used for UI purposes
-PROP_START_BOUND = "StartBound" # Number, lowest address (inclusive) which is valid for the context
-PROP_END_BOUND = "EndBound" # Number, highest address (inclusive) which is valid for the context
-PROP_ACCESS_TYPES = "AccessTypes" # Array of String, the access types allowed for this context
-
-# Values of "AccessTypes".
-# Target system can support multiple different memory access types, like instruction and data access.
-# Different access types can use different logic for address translation and memory mapping, so they can
-# end up accessing different data bits, even if address is the same.
-# Each distinct access type should be represented by separate memory context.
-# A memory context can represent multiple access types if they are equivalent - all access same memory bits.
-# Same data bits can be exposed through multiple memory contexts.
-ACCESS_INSTRUCTION = "instruction" # Context represent instructions fetch access
-ACCESS_DATA = "data" # Context represents data access
-ACCESS_IO = "io" # Context represents IO peripherals
-ACCESS_USER = "user" # Context represents a user (e.g. application running in Linux) view to memory
-ACCESS_SUPERVISOR = "supervisor" # Context represents a supervisor (e.g. Linux kernel) view to memory
-ACCESS_HYPERVISOR = "hypervisor" # Context represents a hypervisor view to memory
-ACCESS_VIRTUAL = "virtual" # Context uses virtual addresses
-ACCESS_PHYSICAL = "physical" # Context uses physical addresses
-ACCESS_CACHE = "cache" # Context is a cache
-ACCESS_TLB = "tlb" # Context is a TLB memory
-
-
-# Memory access mode:
-# Carry on when some of the memory cannot be accessed and
-# return MemoryError at the end if any of the bytes
-# were not processed correctly.
-MODE_CONTINUEONERROR = 0x1
-
-# Memory access mode:
-# Verify result of memory operations (by reading and comparing).
-MODE_VERIFY = 0x2
-
-class MemoryContext(object):
- def __init__(self, props):
- self._props = props or {}
-
- def __str__(self):
- return "[Memory Context %s]" % self._props
-
- def getProperties(self):
- """
- Get context properties. See PROP_* definitions for property names.
- Context properties are read only, clients should not try to modify them.
- @return Map of context properties.
- """
- return self._props
-
- def getID(self):
- """
- Retrieve context ID.
- Same as getProperties().get('ID')
- """
- return self._props.get(PROP_ID)
-
- def getParentID(self):
- """
- Retrieve parent context ID.
- Same as getProperties().get('ParentID')
- """
- return self._props.get(PROP_PARENT_ID)
-
- def getProcessID(self):
- """
- Retrieve context process ID.
- Same as getProperties().get('ProcessID')
- """
- return self._props.get(PROP_PROCESS_ID)
-
- def isBigEndian(self):
- """
- Get memory endianness.
- @return True if memory is big-endian.
- """
- return self._props.get(PROP_BIG_ENDIAN, False)
-
- def getAddressSize(self):
- """
- Get memory address size.
- @return number of bytes used to store memory address value.
- """
- return self._props.get(PROP_ADDRESS_SIZE, 0)
-
- def getName(self):
- """
- Get memory context name.
- The name can be used for UI purposes.
- @return context name.
- """
- return self._props.get(PROP_NAME)
-
- def getStartBound(self):
- """
- Get lowest address (inclusive) which is valid for the context.
- @return lowest address.
- """
- return self._props.get(PROP_START_BOUND)
-
- def getEndBound(self):
- """
- Get highest address (inclusive) which is valid for the context.
- @return highest address.
- """
- return self._props.get(PROP_END_BOUND)
-
- def getAccessTypes(self):
- """
- Get the access types allowed for this context.
- @return collection of access type names.
- """
- return self._props.get(PROP_ACCESS_TYPES)
-
- def set(self, addr, word_size, buf, offs, size, mode, done):
- """
- Set target memory.
- If 'word_size' is 0 it means client does not care about word size.
- """
- raise NotImplementedError("Abstract method")
-
- def get(self, addr, word_size, buf, offs, size, mode, done):
- """
- Read target memory.
- """
- raise NotImplementedError("Abstract method")
-
- def fill(self, addr, word_size, value, size, mode, done):
- """
- Fill target memory with given pattern.
- 'size' is number of bytes to fill.
- """
- raise NotImplementedError("Abstract method")
-
-class DoneMemory(object):
- """
- Client call back interface for set(), get() and fill() commands.
- """
- def doneMemory(self, token, error):
- pass
-
-class MemoryError(Exception):
- pass
-
-class ErrorOffset(object):
- """
- ErrorOffset may be implemented by MemoryError object,
- which is returned by get, set and fill commands.
-
- get/set/fill () returns this exception when reading failed
- for some but not all bytes, and MODE_CONTINUEONERROR
- has been set in mode. (For example, when only part of the request
- translates to valid memory addresses.)
- Exception.getMessage can be used for generalized message of the
- possible reasons of partial memory operation.
- """
- # Error may have per byte information
- BYTE_VALID = 0x00
- BYTE_UNKNOWN = 0x01 # e.g. out of range
- BYTE_INVALID = 0x02
- BYTE_CANNOT_READ = 0x04
- BYTE_CANNOT_WRITE = 0x08
-
- RANGE_KEY_ADDR = "addr"
- RANGE_KEY_SIZE = "size"
- RANGE_KEY_STAT = "stat"
- RANGE_KEY_MSG = "msg"
-
- def getStatus(self, offset):
- raise NotImplementedError("Abstract method")
-
- def getMessage(self, offset):
- raise NotImplementedError("Abstract method")
-
-class MemoryService(services.Service):
- def getName(self):
- return NAME
-
- def getContext(self, id, done):
- """
- Retrieve context info for given context ID.
-
- @param id - context ID.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def getChildren(self, parent_context_id, done):
- """
- Retrieve contexts available for memory commands.
- A context corresponds to an execution thread, process, address space, etc.
- A context can belong to a parent context. Contexts hierarchy can be simple
- plain list or it can form a tree. It is up to target agent developers to choose
- layout that is most descriptive for a given target. Context IDs are valid across
- all services. In other words, all services access same hierarchy of contexts,
- with same IDs, however, each service accesses its own subset of context's
- attributes and functionality, which is relevant to that service.
-
- @param parent_context_id - parent context ID. Can be None -
- to retrieve top level of the hierarchy, or one of context IDs retrieved
- by previous getChildren commands.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def addListener(self, listener):
- """
- Add memory service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
- def removeListener(self, listener):
- """
- Remove memory service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
-class MemoryListener(object):
- """
- Memory event listener is notified when memory context hierarchy
- changes, and when memory is modified by memory service commands.
- """
-
- def contextAdded(self, contexts):
- """
- Called when a new memory access context(s) is created.
- """
- pass
-
- def contextChanged(self, contexts):
- """
- Called when a memory access context(s) properties changed.
- """
- pass
-
- def contextRemoved(self, context_ids):
- """
- Called when memory access context(s) is removed.
- """
- pass
-
- def memoryChanged(self, context_id, addr, size):
- """
- Called when target memory content was changed and clients
- need to update themselves. Clients, at least, should invalidate
- corresponding cached memory data.
- Not every change is notified - it is not possible,
- only those, which are not caused by normal execution of the debuggee.
- 'addr' and 'size' can be None if unknown.
- """
- pass
-
-class DoneGetContext(object):
- """
- Client call back interface for getContext().
- """
- def doneGetContext(self, token, error, context):
- """
- Called when context data retrieval is done.
- @param error - error description if operation failed, None if succeeded.
- @param context - context data.
- """
- pass
-
-class DoneGetChildren(object):
- """
- Client call back interface for getChildren().
- """
- def doneGetChildren(self, token, error, context_ids):
- """
- Called when context list retrieval is done.
- @param error - error description if operation failed, None if succeeded.
- @param context_ids - array of available context IDs.
- """
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Memory service provides basic operations to read/write memory on a target.
+"""
+
+from tcf import services
+
+NAME = "Memory"
+
+# Context property names.
+PROP_ID = "ID" # String, ID of the context, same as getContext command argument
+PROP_PARENT_ID = "ParentID" # String, ID of a parent context
+PROP_PROCESS_ID = "ProcessID" # String, process ID, see Processes service
+PROP_BIG_ENDIAN = "BigEndian" # Boolean, True if memory is big-endian
+PROP_ADDRESS_SIZE = "AddressSize" # Number, size of memory address in bytes
+PROP_NAME = "Name" # String, name of the context, can be used for UI purposes
+PROP_START_BOUND = "StartBound" # Number, lowest address (inclusive) which is valid for the context
+PROP_END_BOUND = "EndBound" # Number, highest address (inclusive) which is valid for the context
+PROP_ACCESS_TYPES = "AccessTypes" # Array of String, the access types allowed for this context
+
+# Values of "AccessTypes".
+# Target system can support multiple different memory access types, like instruction and data access.
+# Different access types can use different logic for address translation and memory mapping, so they can
+# end up accessing different data bits, even if address is the same.
+# Each distinct access type should be represented by separate memory context.
+# A memory context can represent multiple access types if they are equivalent - all access same memory bits.
+# Same data bits can be exposed through multiple memory contexts.
+ACCESS_INSTRUCTION = "instruction" # Context represent instructions fetch access
+ACCESS_DATA = "data" # Context represents data access
+ACCESS_IO = "io" # Context represents IO peripherals
+ACCESS_USER = "user" # Context represents a user (e.g. application running in Linux) view to memory
+ACCESS_SUPERVISOR = "supervisor" # Context represents a supervisor (e.g. Linux kernel) view to memory
+ACCESS_HYPERVISOR = "hypervisor" # Context represents a hypervisor view to memory
+ACCESS_VIRTUAL = "virtual" # Context uses virtual addresses
+ACCESS_PHYSICAL = "physical" # Context uses physical addresses
+ACCESS_CACHE = "cache" # Context is a cache
+ACCESS_TLB = "tlb" # Context is a TLB memory
+
+
+# Memory access mode:
+# Carry on when some of the memory cannot be accessed and
+# return MemoryError at the end if any of the bytes
+# were not processed correctly.
+MODE_CONTINUEONERROR = 0x1
+
+# Memory access mode:
+# Verify result of memory operations (by reading and comparing).
+MODE_VERIFY = 0x2
+
+class MemoryContext(object):
+ def __init__(self, props):
+ self._props = props or {}
+
+ def __str__(self):
+ return "[Memory Context %s]" % self._props
+
+ def getProperties(self):
+ """
+ Get context properties. See PROP_* definitions for property names.
+ Context properties are read only, clients should not try to modify them.
+ @return Map of context properties.
+ """
+ return self._props
+
+ def getID(self):
+ """
+ Retrieve context ID.
+ Same as getProperties().get('ID')
+ """
+ return self._props.get(PROP_ID)
+
+ def getParentID(self):
+ """
+ Retrieve parent context ID.
+ Same as getProperties().get('ParentID')
+ """
+ return self._props.get(PROP_PARENT_ID)
+
+ def getProcessID(self):
+ """
+ Retrieve context process ID.
+ Same as getProperties().get('ProcessID')
+ """
+ return self._props.get(PROP_PROCESS_ID)
+
+ def isBigEndian(self):
+ """
+ Get memory endianness.
+ @return True if memory is big-endian.
+ """
+ return self._props.get(PROP_BIG_ENDIAN, False)
+
+ def getAddressSize(self):
+ """
+ Get memory address size.
+ @return number of bytes used to store memory address value.
+ """
+ return self._props.get(PROP_ADDRESS_SIZE, 0)
+
+ def getName(self):
+ """
+ Get memory context name.
+ The name can be used for UI purposes.
+ @return context name.
+ """
+ return self._props.get(PROP_NAME)
+
+ def getStartBound(self):
+ """
+ Get lowest address (inclusive) which is valid for the context.
+ @return lowest address.
+ """
+ return self._props.get(PROP_START_BOUND)
+
+ def getEndBound(self):
+ """
+ Get highest address (inclusive) which is valid for the context.
+ @return highest address.
+ """
+ return self._props.get(PROP_END_BOUND)
+
+ def getAccessTypes(self):
+ """
+ Get the access types allowed for this context.
+ @return collection of access type names.
+ """
+ return self._props.get(PROP_ACCESS_TYPES)
+
+ def set(self, addr, word_size, buf, offs, size, mode, done):
+ """
+ Set target memory.
+ If 'word_size' is 0 it means client does not care about word size.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def get(self, addr, word_size, buf, offs, size, mode, done):
+ """
+ Read target memory.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def fill(self, addr, word_size, value, size, mode, done):
+ """
+ Fill target memory with given pattern.
+ 'size' is number of bytes to fill.
+ """
+ raise NotImplementedError("Abstract method")
+
+class DoneMemory(object):
+ """
+ Client call back interface for set(), get() and fill() commands.
+ """
+ def doneMemory(self, token, error):
+ pass
+
+class MemoryError(Exception):
+ pass
+
+class ErrorOffset(object):
+ """
+ ErrorOffset may be implemented by MemoryError object,
+ which is returned by get, set and fill commands.
+
+ get/set/fill () returns this exception when reading failed
+ for some but not all bytes, and MODE_CONTINUEONERROR
+ has been set in mode. (For example, when only part of the request
+ translates to valid memory addresses.)
+ Exception.getMessage can be used for generalized message of the
+ possible reasons of partial memory operation.
+ """
+ # Error may have per byte information
+ BYTE_VALID = 0x00
+ BYTE_UNKNOWN = 0x01 # e.g. out of range
+ BYTE_INVALID = 0x02
+ BYTE_CANNOT_READ = 0x04
+ BYTE_CANNOT_WRITE = 0x08
+
+ RANGE_KEY_ADDR = "addr"
+ RANGE_KEY_SIZE = "size"
+ RANGE_KEY_STAT = "stat"
+ RANGE_KEY_MSG = "msg"
+
+ def getStatus(self, offset):
+ raise NotImplementedError("Abstract method")
+
+ def getMessage(self, offset):
+ raise NotImplementedError("Abstract method")
+
+class MemoryService(services.Service):
+ def getName(self):
+ return NAME
+
+ def getContext(self, id, done):
+ """
+ Retrieve context info for given context ID.
+
+ @param id - context ID.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getChildren(self, parent_context_id, done):
+ """
+ Retrieve contexts available for memory commands.
+ A context corresponds to an execution thread, process, address space, etc.
+ A context can belong to a parent context. Contexts hierarchy can be simple
+ plain list or it can form a tree. It is up to target agent developers to choose
+ layout that is most descriptive for a given target. Context IDs are valid across
+ all services. In other words, all services access same hierarchy of contexts,
+ with same IDs, however, each service accesses its own subset of context's
+ attributes and functionality, which is relevant to that service.
+
+ @param parent_context_id - parent context ID. Can be None -
+ to retrieve top level of the hierarchy, or one of context IDs retrieved
+ by previous getChildren commands.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def addListener(self, listener):
+ """
+ Add memory service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def removeListener(self, listener):
+ """
+ Remove memory service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+class MemoryListener(object):
+ """
+ Memory event listener is notified when memory context hierarchy
+ changes, and when memory is modified by memory service commands.
+ """
+
+ def contextAdded(self, contexts):
+ """
+ Called when a new memory access context(s) is created.
+ """
+ pass
+
+ def contextChanged(self, contexts):
+ """
+ Called when a memory access context(s) properties changed.
+ """
+ pass
+
+ def contextRemoved(self, context_ids):
+ """
+ Called when memory access context(s) is removed.
+ """
+ pass
+
+ def memoryChanged(self, context_id, addr, size):
+ """
+ Called when target memory content was changed and clients
+ need to update themselves. Clients, at least, should invalidate
+ corresponding cached memory data.
+ Not every change is notified - it is not possible,
+ only those, which are not caused by normal execution of the debuggee.
+ 'addr' and 'size' can be None if unknown.
+ """
+ pass
+
+class DoneGetContext(object):
+ """
+ Client call back interface for getContext().
+ """
+ def doneGetContext(self, token, error, context):
+ """
+ Called when context data retrieval is done.
+ @param error - error description if operation failed, None if succeeded.
+ @param context - context data.
+ """
+ pass
+
+class DoneGetChildren(object):
+ """
+ Client call back interface for getChildren().
+ """
+ def doneGetChildren(self, token, error, context_ids):
+ """
+ Called when context list retrieval is done.
+ @param error - error description if operation failed, None if succeeded.
+ @param context_ids - array of available context IDs.
+ """
+ pass
diff --git a/python/src/tcf/services/memorymap.py b/python/src/tcf/services/memorymap.py
index 4b805fe97..49c9d4b07 100644
--- a/python/src/tcf/services/memorymap.py
+++ b/python/src/tcf/services/memorymap.py
@@ -1,188 +1,188 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-MemoryMap service provides information about executable modules (files) mapped (loaded) into target memory.
-"""
-
-from tcf import services
-
-NAME = "MemoryMap"
-
-
-# Memory region property names.
-# Number, region address in memory
-PROP_ADDRESS = "Addr"
-
-# Number, region size
-PROP_SIZE = "Size"
-
-# Number, region offset in the file
-PROP_OFFSET = "Offs"
-
-# Boolean, true if the region represents BSS
-PROP_BSS = "BSS"
-
-# Number, region memory protection flags, see FLAG_*
-PROP_FLAGS = "Flags"
-
-# String, name of the file
-PROP_FILE_NAME = "FileName"
-
-# String, name of the object file section
-PROP_SECTION_NAME = "SectionName"
-
-# Memory region flags.
-# Read access is allowed
-FLAG_READ = 1
-
-# Write access is allowed
-FLAG_WRITE = 2
-
-# Instruction fetch access is allowed
-FLAG_EXECUTE = 4
-
-class MemoryRegion(object):
- """Memory region object."""
-
- def __init__(self, props):
- self._props = props
-
- def getProperties(self):
- """
- Get region properties. See PROP_* definitions for property names.
- Properties are read only, clients should not try to modify them.
- @return Map of region properties.
- """
- self._props
-
- def getAddress(self):
- """
- Get memory region address.
- @return region address.
- """
- return self._props.get(PROP_ADDRESS)
-
- def getSize(self):
- """
- Get memory region size.
- @return region size.
- """
- return self._props.get(PROP_SIZE)
-
- def getOffset(self):
- """
- Get memory region file offset.
- @return file offset.
- """
- return self._props.get(PROP_OFFSET)
-
- def getFlags(self):
- """
- Get memory region flags.
- @return region flags.
- """
- return self._props.get(PROP_FLAGS, 0)
-
- def getFileName(self):
- """
- Get memory region file name.
- @return file name.
- """
- return self._props.get(PROP_FILE_NAME)
-
- def getSectionName(self):
- """
- Get memory region section name.
- @return section name.
- """
- return self._props.get(PROP_SECTION_NAME)
-
- def __json__(self):
- # This makes it serializable using JSON serializer
- return self._props
-
- def __repr__(self):
- return "MemoryRegion(%s)" % str(self._props)
- __str__ = __repr__
-
-class MemoryMapService(services.Service):
- def getName(self):
- return NAME
-
- def get(self, id, done):
- """
- Retrieve memory map for given context ID.
-
- @param id - context ID.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def set(self, id, map, done):
- """
- Set memory map for given context ID.
-
- @param id - context ID.
- @param map - memory map data.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def addListener(self, listener):
- """
- Add memory map event listener.
- @param listener - memory map event listener to add.
- """
- return NotImplementedError("Abstract method")
-
- def removeListener(self, listener):
- """
- Remove memory map event listener.
- @param listener - memory map event listener to remove.
- """
- return NotImplementedError("Abstract method")
-
-class DoneGet(object):
- """
- Client call back interface for get().
- """
- def doneGet(self, token, error, map):
- """
- Called when memory map data retrieval is done.
- @param error - error description if operation failed, None if succeeded.
- @param map - memory map data.
- """
- pass
-
-class DoneSet(object):
- """
- Client call back interface for set().
- """
- def doneSet(self, token, error):
- """
- Called when memory map set command is done.
- @param error - error description if operation failed, None if succeeded.
- """
- pass
-
-class MemoryMapListener(object):
- """
- Service events listener interface.
- """
- def changed(self, context_id):
- """
- Called when context memory map changes.
- @param context_id - context ID.
- """
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+MemoryMap service provides information about executable modules (files) mapped (loaded) into target memory.
+"""
+
+from tcf import services
+
+NAME = "MemoryMap"
+
+
+# Memory region property names.
+# Number, region address in memory
+PROP_ADDRESS = "Addr"
+
+# Number, region size
+PROP_SIZE = "Size"
+
+# Number, region offset in the file
+PROP_OFFSET = "Offs"
+
+# Boolean, true if the region represents BSS
+PROP_BSS = "BSS"
+
+# Number, region memory protection flags, see FLAG_*
+PROP_FLAGS = "Flags"
+
+# String, name of the file
+PROP_FILE_NAME = "FileName"
+
+# String, name of the object file section
+PROP_SECTION_NAME = "SectionName"
+
+# Memory region flags.
+# Read access is allowed
+FLAG_READ = 1
+
+# Write access is allowed
+FLAG_WRITE = 2
+
+# Instruction fetch access is allowed
+FLAG_EXECUTE = 4
+
+class MemoryRegion(object):
+ """Memory region object."""
+
+ def __init__(self, props):
+ self._props = props
+
+ def getProperties(self):
+ """
+ Get region properties. See PROP_* definitions for property names.
+ Properties are read only, clients should not try to modify them.
+ @return Map of region properties.
+ """
+ self._props
+
+ def getAddress(self):
+ """
+ Get memory region address.
+ @return region address.
+ """
+ return self._props.get(PROP_ADDRESS)
+
+ def getSize(self):
+ """
+ Get memory region size.
+ @return region size.
+ """
+ return self._props.get(PROP_SIZE)
+
+ def getOffset(self):
+ """
+ Get memory region file offset.
+ @return file offset.
+ """
+ return self._props.get(PROP_OFFSET)
+
+ def getFlags(self):
+ """
+ Get memory region flags.
+ @return region flags.
+ """
+ return self._props.get(PROP_FLAGS, 0)
+
+ def getFileName(self):
+ """
+ Get memory region file name.
+ @return file name.
+ """
+ return self._props.get(PROP_FILE_NAME)
+
+ def getSectionName(self):
+ """
+ Get memory region section name.
+ @return section name.
+ """
+ return self._props.get(PROP_SECTION_NAME)
+
+ def __json__(self):
+ # This makes it serializable using JSON serializer
+ return self._props
+
+ def __repr__(self):
+ return "MemoryRegion(%s)" % str(self._props)
+ __str__ = __repr__
+
+class MemoryMapService(services.Service):
+ def getName(self):
+ return NAME
+
+ def get(self, id, done):
+ """
+ Retrieve memory map for given context ID.
+
+ @param id - context ID.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def set(self, id, map, done):
+ """
+ Set memory map for given context ID.
+
+ @param id - context ID.
+ @param map - memory map data.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def addListener(self, listener):
+ """
+ Add memory map event listener.
+ @param listener - memory map event listener to add.
+ """
+ return NotImplementedError("Abstract method")
+
+ def removeListener(self, listener):
+ """
+ Remove memory map event listener.
+ @param listener - memory map event listener to remove.
+ """
+ return NotImplementedError("Abstract method")
+
+class DoneGet(object):
+ """
+ Client call back interface for get().
+ """
+ def doneGet(self, token, error, map):
+ """
+ Called when memory map data retrieval is done.
+ @param error - error description if operation failed, None if succeeded.
+ @param map - memory map data.
+ """
+ pass
+
+class DoneSet(object):
+ """
+ Client call back interface for set().
+ """
+ def doneSet(self, token, error):
+ """
+ Called when memory map set command is done.
+ @param error - error description if operation failed, None if succeeded.
+ """
+ pass
+
+class MemoryMapListener(object):
+ """
+ Service events listener interface.
+ """
+ def changed(self, context_id):
+ """
+ Called when context memory map changes.
+ @param context_id - context ID.
+ """
+ pass
diff --git a/python/src/tcf/services/pathmap.py b/python/src/tcf/services/pathmap.py
index c232f15ef..588818dbb 100644
--- a/python/src/tcf/services/pathmap.py
+++ b/python/src/tcf/services/pathmap.py
@@ -1,153 +1,153 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-PathMap service manages file path translation across systems.
-"""
-
-from tcf import services
-
-NAME = "PathMap"
-
-# Path mapping rule property names.
-# String, rule ID
-PROP_ID = "ID"
-
-# String, source, or compile-time file path
-PROP_SOURCE = "Source"
-
-# String, destination, or run-time file path
-PROP_DESTINATION = "Destination"
-
-# String
-PROP_HOST = "Host"
-
-# String, file access protocol, see PROTOCOL_*, default is regular file
-PROP_PROTOCOL = "Protocol"
-
-# PROP_PROTOCOL values.
-# Regular file access using system calls
-PROTOCOL_FILE = "file"
-
-# File should be accessed using File System service on host
-PROTOCOL_HOST = "host"
-
-# File should be accessed using File System service on target
-PROTOCOL_TARGET = "target"
-
-class PathMapRule(object):
- """
- PathMapRule represents a single file path mapping rule.
- """
- def __init__(self, props):
- self._props = props or {}
-
- def __str__(self):
- return str(self._props)
-
- def __json__(self):
- return self._props
-
- def getProperties(self):
- """
- Get rule properties. See PROP_* definitions for property names.
- Context properties are read only, clients should not try to modify them.
- @return Map of rule properties.
- """
- return self._props
-
- def getID(self):
- """
- Get rule unique ID.
- Same as getProperties().get(PROP_ID)
- @return rule ID.
- """
- return self._props.get(PROP_ID)
-
- def getSource(self):
- """
- Get compile-time file path.
- Same as getProperties().get(PROP_SOURCE)
- @return compile-time file path.
- """
- return self._props.get(PROP_SOURCE)
-
- def getDestination(self):
- """
- Get run-time file path.
- Same as getProperties().get(PROP_DESTINATION)
- @return run-time file path.
- """
- return self._props.get(PROP_DESTINATION)
-
- def getHost(self):
- """
- Get host name of this rule.
- Same as getProperties().get(PROP_HOST)
- @return host name.
- """
- return self._props.get(PROP_HOST)
-
- def getProtocol(self):
- """
- Get file access protocol name.
- Same as getProperties().get(PROP_PROTOCOL)
- @return protocol name.
- """
- return self._props.get(PROP_PROTOCOL)
-
-
-class PathMapService(services.Service):
- def getName(self):
- return NAME
-
- def get(self, done):
- """
- Retrieve file path mapping rules.
-
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
- def set(self, map, done):
- """
- Set file path mapping rules.
-
- @param map - file path mapping rules.
- @param done - call back interface called when operation is completed.
- @return - pending command handle.
- """
- return NotImplementedError("Abstract method")
-
-class DoneGet(object):
- """
- Client call back interface for get().
- """
- def doneGet(self, token, error, map):
- """
- Called when file path mapping retrieval is done.
- @param error - error description if operation failed, None if succeeded.
- @param map - file path mapping data.
- """
- pass
-
-class DoneSet(object):
- """
- Client call back interface for set().
- """
- def doneSet(self, token, error):
- """
- Called when file path mapping transmission is done.
- @param error - error description if operation failed, None if succeeded.
- @param map - memory map data.
- """
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+PathMap service manages file path translation across systems.
+"""
+
+from tcf import services
+
+NAME = "PathMap"
+
+# Path mapping rule property names.
+# String, rule ID
+PROP_ID = "ID"
+
+# String, source, or compile-time file path
+PROP_SOURCE = "Source"
+
+# String, destination, or run-time file path
+PROP_DESTINATION = "Destination"
+
+# String
+PROP_HOST = "Host"
+
+# String, file access protocol, see PROTOCOL_*, default is regular file
+PROP_PROTOCOL = "Protocol"
+
+# PROP_PROTOCOL values.
+# Regular file access using system calls
+PROTOCOL_FILE = "file"
+
+# File should be accessed using File System service on host
+PROTOCOL_HOST = "host"
+
+# File should be accessed using File System service on target
+PROTOCOL_TARGET = "target"
+
+class PathMapRule(object):
+ """
+ PathMapRule represents a single file path mapping rule.
+ """
+ def __init__(self, props):
+ self._props = props or {}
+
+ def __str__(self):
+ return str(self._props)
+
+ def __json__(self):
+ return self._props
+
+ def getProperties(self):
+ """
+ Get rule properties. See PROP_* definitions for property names.
+ Context properties are read only, clients should not try to modify them.
+ @return Map of rule properties.
+ """
+ return self._props
+
+ def getID(self):
+ """
+ Get rule unique ID.
+ Same as getProperties().get(PROP_ID)
+ @return rule ID.
+ """
+ return self._props.get(PROP_ID)
+
+ def getSource(self):
+ """
+ Get compile-time file path.
+ Same as getProperties().get(PROP_SOURCE)
+ @return compile-time file path.
+ """
+ return self._props.get(PROP_SOURCE)
+
+ def getDestination(self):
+ """
+ Get run-time file path.
+ Same as getProperties().get(PROP_DESTINATION)
+ @return run-time file path.
+ """
+ return self._props.get(PROP_DESTINATION)
+
+ def getHost(self):
+ """
+ Get host name of this rule.
+ Same as getProperties().get(PROP_HOST)
+ @return host name.
+ """
+ return self._props.get(PROP_HOST)
+
+ def getProtocol(self):
+ """
+ Get file access protocol name.
+ Same as getProperties().get(PROP_PROTOCOL)
+ @return protocol name.
+ """
+ return self._props.get(PROP_PROTOCOL)
+
+
+class PathMapService(services.Service):
+ def getName(self):
+ return NAME
+
+ def get(self, done):
+ """
+ Retrieve file path mapping rules.
+
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+ def set(self, map, done):
+ """
+ Set file path mapping rules.
+
+ @param map - file path mapping rules.
+ @param done - call back interface called when operation is completed.
+ @return - pending command handle.
+ """
+ return NotImplementedError("Abstract method")
+
+class DoneGet(object):
+ """
+ Client call back interface for get().
+ """
+ def doneGet(self, token, error, map):
+ """
+ Called when file path mapping retrieval is done.
+ @param error - error description if operation failed, None if succeeded.
+ @param map - file path mapping data.
+ """
+ pass
+
+class DoneSet(object):
+ """
+ Client call back interface for set().
+ """
+ def doneSet(self, token, error):
+ """
+ Called when file path mapping transmission is done.
+ @param error - error description if operation failed, None if succeeded.
+ @param map - memory map data.
+ """
+ pass
diff --git a/python/src/tcf/services/processes.py b/python/src/tcf/services/processes.py
index d5ddef0ca..e7addb3b9 100644
--- a/python/src/tcf/services/processes.py
+++ b/python/src/tcf/services/processes.py
@@ -1,340 +1,340 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-IProcesses service provides access to the target OS's process
-information, allows to start and terminate a process, and allows
-to attach and detach a process for debugging. Debug services,
-like IMemory and IRunControl, require a process to be attached
-before they can access it.
-
-If a process is started by this service, its standard input/output streams are
-available for client to read/write using Streams service. Stream type of such
-streams is set to "Processes".
-"""
-
-from tcf import services
-
-NAME = "Processes"
-
-# Context property names.
-
-# The TCF context ID
-PROP_ID = "ID"
-
-# The TCF parent context ID
-PROP_PARENT_ID = "ParentID"
-
-# Is the context attached
-PROP_ATTACHED = "Attached"
-
-# Can terminate the context
-PROP_CAN_TERMINATE = "CanTerminate"
-
-# Process name. Client UI can show this name to a user
-PROP_NAME = "Name"
-
-# Process standard input stream ID
-PROP_STDIN_ID = "StdInID"
-
-# Process standard output stream ID
-PROP_STDOUT_ID = "StdOutID"
-
-# Process standard error stream ID
-PROP_STDERR_ID = "StdErrID"
-
-
-# Signal property names used by "getSignalList" command.
-
-# Number, bit position in the signal mask
-SIG_INDEX = "Index"
-
-#String, signal name, for example "SIGHUP"
-SIG_NAME = "Name"
-
-# Number, signal code, as defined by OS
-SIG_CODE = "Code"
-
-# String, human readable description of the signal
-SIG_DESCRIPTION = "Description"
-
-
-class ProcessesService(services.Service):
- def getName(self):
- return NAME
-
- def getContext(self, id, done):
- """
- Retrieve context info for given context ID.
- A context corresponds to an execution thread, process, address space, etc.
- Context IDs are valid across TCF services, so it is allowed to issue
- 'IProcesses.getContext' command with a context that was obtained,
- for example, from Memory service.
- However, 'Processes.getContext' is supposed to return only process specific data,
- If the ID is not a process ID, 'IProcesses.getContext' may not return any
- useful information
-
- @param id - context ID.
- @param done - call back interface called when operation is completed.
- """
- raise NotImplementedError("Abstract method")
-
- def getChildren(self, parent_context_id, attached_only, done):
- """
- Retrieve children of given context.
-
- @param parent_context_id - parent context ID. Can be None -
- to retrieve top level of the hierarchy, or one of context IDs retrieved
- by previous getContext or getChildren commands.
- @param attached_only - if True return only attached process IDs.
- @param done - call back interface called when operation is completed.
- """
- raise NotImplementedError("Abstract method")
-
- def getSignalList(self, context_id, done):
- """
- Get list of signals that can be send to the process.
- @param context_id - process context ID or None.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def getSignalMask(self, context_id, done):
- """
- Get process or thread signal mask.
- Bits in the mask control how signals should be handled by debug agent.
- When new context is created it inherits the mask from its parent.
- If context is not attached the command will return an error.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def setSignalMask(self, context_id, dont_stop, dont_pass, done):
- """
- Set process or thread signal mask.
- Bits in the mask control how signals should be handled by debug agent.
- If context is not attached the command will return an error.
- @param dont_stop - bit-set of signals that should not suspend execution of the context.
- By default, debugger suspends a context before it receives a signal.
- @param dont_pass - bit-set of signals that should not be delivered to the context.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def signal(self, context_id, signal, done):
- """
- Send a signal to a process or thread.
- @param context_id - context ID.
- @param signal - signal code.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def getEnvironment(self, done):
- """
- Get default set of environment variables used to start a new process.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def start(self, directory, file, command_line, environment, attach, done):
- """
- Start a new process on remote machine.
- @param directory - initial value of working directory for the process.
- @param file - process image file.
- @param command_line - command line arguments for the process.
- Note: the service does NOT add image file name as first argument for the process.
- If a client wants first parameter to be the file name, it should add it itself.
- @param environment - map of environment variables for the process,
- if None then default set of environment variables will be used.
- @param attach - if True debugger should be attached to the process.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def addListener(self, listener):
- """
- Add processes service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
- def removeListener(self, listener):
- """
- Remove processes service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
-
-class ProcessContext(object):
- def __init__(self, props):
- self._props = props or {}
-
- def __str__(self):
- return "[Processes Context %s]" % self._props
-
- def getProperties(self):
- """
- Get context properties. See PROP_* definitions for property names.
- Context properties are read only, clients should not try to modify them.
- @return Map of context properties.
- """
- return self._props
-
- def getID(self):
- """
- Retrieve context ID.
- Same as getProperties().get('ID')
- """
- return self._props.get(PROP_ID)
-
- def getParentID(self):
- """
- Retrieve parent context ID.
- Same as getProperties().get('ParentID')
- """
- return self._props.get(PROP_PARENT_ID)
-
- def getName(self):
- """
- Retrieve human readable context name.
- Same as getProperties().get('Name')
- """
- return self._props.get(PROP_NAME)
-
- def isAttached(self):
- """
- Utility method to read context property PROP_ATTACHED.
- Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
- @return value of PROP_ATTACHED.
- """
- return self._props.get(PROP_ATTACHED)
-
- def canTerminate(self):
- """
- Utility method to read context property PROP_CAN_TERMINATE.
- @return value of PROP_CAN_TERMINATE.
- """
- return self._props.get(PROP_CAN_TERMINATE)
-
- def attach(self, done):
- """
- Attach debugger to a process.
- Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def detach(self, done):
- """
- Detach debugger from a process.
- Process execution will continue without debugger supervision.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
- def terminate(self, done):
- """
- Terminate a process.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
-
-class DoneCommand(object):
- """
- Call-back interface to be called when command is complete.
- """
- def doneCommand(self, token, error):
- pass
-
-class DoneGetContext(object):
- """
- Client call back interface for getContext().
- """
- def doneGetContext(self, token, error, context):
- """
- Called when context data retrieval is done.
- @param error - error description if operation failed, None if succeeded.
- @param context - context data.
- """
- pass
-
-class DoneGetChildren(object):
- """
- Client call back interface for getChildren().
- """
- def doneGetChildren(self, token, error, context_ids):
- """
- Called when context list retrieval is done.
- @param error - error description if operation failed, None if succeeded.
- @param context_ids - array of available context IDs.
- """
- pass
-
-class DoneGetSignalList(object):
- """
- Call-back interface to be called when "getSignalList" command is complete.
- """
- def doneGetSignalList(self, token, error, list):
- pass
-
-class DoneGetSignalMask(object):
- """
- Call-back interface to be called when "getSignalMask" command is complete.
- """
- def doneGetSignalMask(self, token, error, dont_stop, dont_pass, pending):
- """
- @param token - command handle.
- @param dont_stop - bit-set of signals that should suspend execution of the context.
- @param dont_pass - bit-set of signals that should not be delivered to the context.
- @param pending - bit-set of signals that are generated but not delivered yet.
- Note: "pending" is meaningful only if the context is suspended.
- """
- pass
-
-class DoneGetEnvironment(object):
- """
- Call-back interface to be called when "getEnvironment" command is complete.
- """
- def doneGetEnvironment(self, token, error, environment):
- pass
-
-class DoneStart(object):
- """
- Call-back interface to be called when "start" command is complete.
- """
- def doneStart(self, token, error, process):
- pass
-
-class ProcessesListener(object):
- """
- Process event listener is notified when a process exits.
- Event are reported only for processes that were started by 'start' command.
- """
-
- def exited(self, process_id, exit_code):
- """
- Called when a process exits.
- @param process_id - process context ID
- @param exit_code - if >= 0 - the process exit code,
- if < 0 - process was terminated by a signal, the signal code = -exit_code.
- """
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+IProcesses service provides access to the target OS's process
+information, allows to start and terminate a process, and allows
+to attach and detach a process for debugging. Debug services,
+like IMemory and IRunControl, require a process to be attached
+before they can access it.
+
+If a process is started by this service, its standard input/output streams are
+available for client to read/write using Streams service. Stream type of such
+streams is set to "Processes".
+"""
+
+from tcf import services
+
+NAME = "Processes"
+
+# Context property names.
+
+# The TCF context ID
+PROP_ID = "ID"
+
+# The TCF parent context ID
+PROP_PARENT_ID = "ParentID"
+
+# Is the context attached
+PROP_ATTACHED = "Attached"
+
+# Can terminate the context
+PROP_CAN_TERMINATE = "CanTerminate"
+
+# Process name. Client UI can show this name to a user
+PROP_NAME = "Name"
+
+# Process standard input stream ID
+PROP_STDIN_ID = "StdInID"
+
+# Process standard output stream ID
+PROP_STDOUT_ID = "StdOutID"
+
+# Process standard error stream ID
+PROP_STDERR_ID = "StdErrID"
+
+
+# Signal property names used by "getSignalList" command.
+
+# Number, bit position in the signal mask
+SIG_INDEX = "Index"
+
+#String, signal name, for example "SIGHUP"
+SIG_NAME = "Name"
+
+# Number, signal code, as defined by OS
+SIG_CODE = "Code"
+
+# String, human readable description of the signal
+SIG_DESCRIPTION = "Description"
+
+
+class ProcessesService(services.Service):
+ def getName(self):
+ return NAME
+
+ def getContext(self, id, done):
+ """
+ Retrieve context info for given context ID.
+ A context corresponds to an execution thread, process, address space, etc.
+ Context IDs are valid across TCF services, so it is allowed to issue
+ 'IProcesses.getContext' command with a context that was obtained,
+ for example, from Memory service.
+ However, 'Processes.getContext' is supposed to return only process specific data,
+ If the ID is not a process ID, 'IProcesses.getContext' may not return any
+ useful information
+
+ @param id - context ID.
+ @param done - call back interface called when operation is completed.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getChildren(self, parent_context_id, attached_only, done):
+ """
+ Retrieve children of given context.
+
+ @param parent_context_id - parent context ID. Can be None -
+ to retrieve top level of the hierarchy, or one of context IDs retrieved
+ by previous getContext or getChildren commands.
+ @param attached_only - if True return only attached process IDs.
+ @param done - call back interface called when operation is completed.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getSignalList(self, context_id, done):
+ """
+ Get list of signals that can be send to the process.
+ @param context_id - process context ID or None.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getSignalMask(self, context_id, done):
+ """
+ Get process or thread signal mask.
+ Bits in the mask control how signals should be handled by debug agent.
+ When new context is created it inherits the mask from its parent.
+ If context is not attached the command will return an error.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def setSignalMask(self, context_id, dont_stop, dont_pass, done):
+ """
+ Set process or thread signal mask.
+ Bits in the mask control how signals should be handled by debug agent.
+ If context is not attached the command will return an error.
+ @param dont_stop - bit-set of signals that should not suspend execution of the context.
+ By default, debugger suspends a context before it receives a signal.
+ @param dont_pass - bit-set of signals that should not be delivered to the context.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def signal(self, context_id, signal, done):
+ """
+ Send a signal to a process or thread.
+ @param context_id - context ID.
+ @param signal - signal code.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getEnvironment(self, done):
+ """
+ Get default set of environment variables used to start a new process.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def start(self, directory, file, command_line, environment, attach, done):
+ """
+ Start a new process on remote machine.
+ @param directory - initial value of working directory for the process.
+ @param file - process image file.
+ @param command_line - command line arguments for the process.
+ Note: the service does NOT add image file name as first argument for the process.
+ If a client wants first parameter to be the file name, it should add it itself.
+ @param environment - map of environment variables for the process,
+ if None then default set of environment variables will be used.
+ @param attach - if True debugger should be attached to the process.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def addListener(self, listener):
+ """
+ Add processes service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def removeListener(self, listener):
+ """
+ Remove processes service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+
+class ProcessContext(object):
+ def __init__(self, props):
+ self._props = props or {}
+
+ def __str__(self):
+ return "[Processes Context %s]" % self._props
+
+ def getProperties(self):
+ """
+ Get context properties. See PROP_* definitions for property names.
+ Context properties are read only, clients should not try to modify them.
+ @return Map of context properties.
+ """
+ return self._props
+
+ def getID(self):
+ """
+ Retrieve context ID.
+ Same as getProperties().get('ID')
+ """
+ return self._props.get(PROP_ID)
+
+ def getParentID(self):
+ """
+ Retrieve parent context ID.
+ Same as getProperties().get('ParentID')
+ """
+ return self._props.get(PROP_PARENT_ID)
+
+ def getName(self):
+ """
+ Retrieve human readable context name.
+ Same as getProperties().get('Name')
+ """
+ return self._props.get(PROP_NAME)
+
+ def isAttached(self):
+ """
+ Utility method to read context property PROP_ATTACHED.
+ Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
+ @return value of PROP_ATTACHED.
+ """
+ return self._props.get(PROP_ATTACHED)
+
+ def canTerminate(self):
+ """
+ Utility method to read context property PROP_CAN_TERMINATE.
+ @return value of PROP_CAN_TERMINATE.
+ """
+ return self._props.get(PROP_CAN_TERMINATE)
+
+ def attach(self, done):
+ """
+ Attach debugger to a process.
+ Services like IRunControl, IMemory, IBreakpoints work only with attached processes.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def detach(self, done):
+ """
+ Detach debugger from a process.
+ Process execution will continue without debugger supervision.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def terminate(self, done):
+ """
+ Terminate a process.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
+
+class DoneCommand(object):
+ """
+ Call-back interface to be called when command is complete.
+ """
+ def doneCommand(self, token, error):
+ pass
+
+class DoneGetContext(object):
+ """
+ Client call back interface for getContext().
+ """
+ def doneGetContext(self, token, error, context):
+ """
+ Called when context data retrieval is done.
+ @param error - error description if operation failed, None if succeeded.
+ @param context - context data.
+ """
+ pass
+
+class DoneGetChildren(object):
+ """
+ Client call back interface for getChildren().
+ """
+ def doneGetChildren(self, token, error, context_ids):
+ """
+ Called when context list retrieval is done.
+ @param error - error description if operation failed, None if succeeded.
+ @param context_ids - array of available context IDs.
+ """
+ pass
+
+class DoneGetSignalList(object):
+ """
+ Call-back interface to be called when "getSignalList" command is complete.
+ """
+ def doneGetSignalList(self, token, error, list):
+ pass
+
+class DoneGetSignalMask(object):
+ """
+ Call-back interface to be called when "getSignalMask" command is complete.
+ """
+ def doneGetSignalMask(self, token, error, dont_stop, dont_pass, pending):
+ """
+ @param token - command handle.
+ @param dont_stop - bit-set of signals that should suspend execution of the context.
+ @param dont_pass - bit-set of signals that should not be delivered to the context.
+ @param pending - bit-set of signals that are generated but not delivered yet.
+ Note: "pending" is meaningful only if the context is suspended.
+ """
+ pass
+
+class DoneGetEnvironment(object):
+ """
+ Call-back interface to be called when "getEnvironment" command is complete.
+ """
+ def doneGetEnvironment(self, token, error, environment):
+ pass
+
+class DoneStart(object):
+ """
+ Call-back interface to be called when "start" command is complete.
+ """
+ def doneStart(self, token, error, process):
+ pass
+
+class ProcessesListener(object):
+ """
+ Process event listener is notified when a process exits.
+ Event are reported only for processes that were started by 'start' command.
+ """
+
+ def exited(self, process_id, exit_code):
+ """
+ Called when a process exits.
+ @param process_id - process context ID
+ @param exit_code - if >= 0 - the process exit code,
+ if < 0 - process was terminated by a signal, the signal code = -exit_code.
+ """
+ pass
diff --git a/python/src/tcf/services/processes_v1.py b/python/src/tcf/services/processes_v1.py
index 75aacd64f..0e31f4cfc 100644
--- a/python/src/tcf/services/processes_v1.py
+++ b/python/src/tcf/services/processes_v1.py
@@ -1,47 +1,47 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Extension of Processes service.
-It provides new "start" command that supports additional parameters.
-"""
-
-from . import processes
-
-NAME = "ProcessesV1"
-
-# Process start parameters
-# Boolean, attach the debugger to the process
-START_ATTACH = "Attach"
-# Boolean, auto-attach process children
-START_ATTACH_CHILDREN = "AttachChildren"
-# Boolean, Use pseudo-terminal for the process standard I/O
-START_USE_TERMINAL = "UseTerminal"
-
-class ProcessesV1Service(processes.ProcessesService):
- def getName(self):
- return NAME
-
- def start(self, directory, file, command_line, environment, params, done):
- """
- Start a new process on remote machine.
- @param directory - initial value of working directory for the process.
- @param file - process image file.
- @param command_line - command line arguments for the process.
- Note: the service does NOT add image file name as first argument for the process.
- If a client wants first parameter to be the file name, it should add it itself.
- @param environment - map of environment variables for the process,
- if None then default set of environment variables will be used.
- @param params - additional process start parameters as map, see START_* for supported keys.
- @param done - call back interface called when operation is completed.
- @return pending command handle, can be used to cancel the command.
- """
- raise NotImplementedError("Abstract method")
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Extension of Processes service.
+It provides new "start" command that supports additional parameters.
+"""
+
+from . import processes
+
+NAME = "ProcessesV1"
+
+# Process start parameters
+# Boolean, attach the debugger to the process
+START_ATTACH = "Attach"
+# Boolean, auto-attach process children
+START_ATTACH_CHILDREN = "AttachChildren"
+# Boolean, Use pseudo-terminal for the process standard I/O
+START_USE_TERMINAL = "UseTerminal"
+
+class ProcessesV1Service(processes.ProcessesService):
+ def getName(self):
+ return NAME
+
+ def start(self, directory, file, command_line, environment, params, done):
+ """
+ Start a new process on remote machine.
+ @param directory - initial value of working directory for the process.
+ @param file - process image file.
+ @param command_line - command line arguments for the process.
+ Note: the service does NOT add image file name as first argument for the process.
+ If a client wants first parameter to be the file name, it should add it itself.
+ @param environment - map of environment variables for the process,
+ if None then default set of environment variables will be used.
+ @param params - additional process start parameters as map, see START_* for supported keys.
+ @param done - call back interface called when operation is completed.
+ @return pending command handle, can be used to cancel the command.
+ """
+ raise NotImplementedError("Abstract method")
diff --git a/python/src/tcf/services/registers.py b/python/src/tcf/services/registers.py
index 6b8e9556b..dff4f4a69 100644
--- a/python/src/tcf/services/registers.py
+++ b/python/src/tcf/services/registers.py
@@ -1,468 +1,468 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-Registers service provides access to target CPU register values and properties.
-"""
-
-from tcf import services
-
-NAME = "Registers"
-
-# Context property names.
-PROP_ID = "ID" # String, ID of the context
-PROP_PARENT_ID = "ParentID" # String, ID of a parent context
-PROP_PROCESS_ID = "ProcessID" # String, process ID
-PROP_NAME = "Name" # String, context name
-PROP_DESCRIPTION = "Description" # String, context description
-PROP_SIZE = "Size" # Number, context size in bytes. Byte arrays in get/set commands should be same size
-PROP_READBLE = "Readable" # Boolean, true if context value can be read
-PROP_READ_ONCE = "ReadOnce" # Boolean, true if reading the context (register) destroys its current value
-PROP_WRITEABLE = "Writeable" # Boolean, true if context value can be written
-PROP_WRITE_ONCE = "WriteOnce" # Boolean, true if register value can not be overwritten - every write counts
-PROP_SIDE_EFFECTS = "SideEffects" # Boolean, true if writing the context can change values of other registers
-PROP_VOLATILE = "Volatile" # Boolean, true if the register value can change even when target is stopped
-PROP_FLOAT = "Float" # Boolean, true if the register value is a floating-point value
-PROP_BIG_ENDIAN = "BigEndian" # Boolean, true if big endian
-PROP_LEFT_TO_RIGHT = "LeftToRight" # Boolean, true if the lowest numbered bit should be shown to user as the left-most bit
-PROP_FIST_BIT = "FirstBit" # Number, bit numbering base (0 or 1) to use when showing bits to user
-PROP_BITS = "Bits" # Number, if context is a bit field, contains the field bit numbers in the parent context
-PROP_VALUES = "Values" # Array of Map, predefined names (mnemonics) for some of context values
-PROP_MEMORY_ADDRESS = "MemoryAddress" # Number, the address of a memory mapped register
-PROP_MEMORY_CONTEXT = "MemoryContext" # String, the context ID of a memory context in which a memory mapped register is located
-PROP_CAN_SEARCH = "CanSearch" # Array of String, a list of attribute names which can be searched for starting on this context
-PROP_ROLE = "Role" # String, the role the register plays in a program execution
-
-# Values of context property "Role".
-ROLE_PC = "PC" # Program counter. Defines instruction to execute next
-ROLE_SP = "SP" # Register defining the current stack pointer location
-ROLE_FP = "FP" # Register defining the current frame pointer location
-ROLE_RET = "RET" # Register used to store the return address for calls
-ROLE_CORE = "CORE" # Indicates register or register groups which belong to the core state
-
-# Search filter properties.
-SEARCH_NAME = "Name" # The name of the property this filter applies too
-SEARCH_EQUAL_VALUE = "EqualValue" # The value which is searched for
-
-
-class RegistersContext(object):
- """
- RegistersContext objects represent register groups, registers and bit fields.
- """
- def __init__(self, props):
- self._props = props or {}
-
- def __str__(self):
- return "[Registers Context %s]" % self._props
-
- def getProperties(self):
- """
- Get context properties. See PROP_* definitions for property names.
- Context properties are read only, clients should not try to modify them.
- @return Map of context properties.
- """
- return self._props
-
- def getID(self):
- """
- Get Context ID.
- @return context ID.
- """
- return self._props.get(PROP_ID)
-
- def getParentID(self):
- """
- Get parent context ID.
- @return parent context ID.
- """
- return self._props.get(PROP_PARENT_ID)
-
- def getProcessID(self):
- """
- Get process ID, if applicable.
- @return process ID.
- """
- return self._props.get(PROP_PROCESS_ID)
-
- def getName(self):
- """
- Get context (register, register group, bit field) name.
- @return context name.
- """
- return self._props.get(PROP_NAME)
-
- def getDescription(self):
- """
- Get context description.
- @return context description.
- """
- return self._props.get(PROP_DESCRIPTION)
-
- def getSize(self):
- """
- Get context size in bytes.
- Byte arrays in get()/set() methods should be same size.
- Hardware register can be smaller then this size, for example in case
- when register size is not an even number of bytes. In such case implementation
- should add/remove padding that consist of necessary number of zero bits.
- @return context size in bytes.
- """
- return self._props.get(PROP_SIZE, 0)
-
- def isReadable(self):
- """
- Check if context value can be read.
- @return true if can read value of the context.
- """
- return self._props.get(PROP_READBLE)
-
- def isReadOnce(self):
- """
- Check if reading the context (register) destroys its current value -
- it can be read only once.
- @return true if read-once register.
- """
- return self._props.get(PROP_READ_ONCE)
-
- def isWriteable(self):
- """
- Check if context value can be written.
- @return true if can write value of the context.
- """
- return self._props.get(PROP_WRITEABLE)
-
- def isWriteOnce(self):
- """
- Check if register value can not be overwritten - every write counts.
- @return true if write-once register.
- """
- return self._props.get(PROP_WRITE_ONCE)
-
- def hasSideEffects(self):
- """
- Check if writing the context can change values of other registers.
- @return true if has side effects.
- """
- return self._props.get(PROP_SIDE_EFFECTS)
-
- def isVolatile(self):
- """
- Check if the register value can change even when target is stopped.
- @return true if the register value can change at any time.
- """
- return self._props.get(PROP_VOLATILE)
-
- def isFloat(self):
- """
- Check if the register value is a floating-point value.
- @return true if a floating-point register.
- """
- return self._props.get(PROP_FLOAT)
-
- def isBigEndian(self):
- """
- Check endianness of the context.
- Big endian means decreasing numeric significance with increasing bit number.
- The endianness is used to encode and decode values of get, getm, set and setm commands.
- @return true if big endian.
- """
- return self._props.get(PROP_BIG_ENDIAN)
-
- def isLeftToRight(self):
- """
- Check if the lowest numbered bit (i.e. bit #0 or bit #1 depending on
- getFirstBitNumber() value) should be shown to user as the left-most bit or
- the right-most bit.
- @return true if the first bit is left-most bit.
- """
- return self._props.get(PROP_LEFT_TO_RIGHT)
-
- def getFirstBitNumber(self):
- """
- If the context has bit field children, bit positions of the fields
- can be zero-based or 1-based.
- @return first bit position - 0 or 1.
- """
- return self._props.get(PROP_FIST_BIT, 0)
-
- def getBitNumbers(self):
- """
- If context is a bit field, get the field bit numbers in parent context.
- @return array of bit numbers.
- """
- return self._props.get(PROP_BITS)
-
- def getNamedValues(self):
- """
- A context can have predefined names (mnemonics) for some its values.
- This method returns a list of such named values.
- @return array of named values or None.
- """
- return self._props.get(PROP_VALUES)
-
- def getMemoryAddress(self):
- """
- Get the address of a memory mapped register.
- @return address.
- """
- return self._props.get(PROP_MEMORY_ADDRESS)
-
- def getMemoryContext(self):
- """
- Get the context ID of a memory context in which a memory mapped register is located.
- @return memory context ID.
- """
- return self._props.get(PROP_MEMORY_CONTEXT)
-
- def canSearch(self):
- """
- Get a list of property names which can be searched for starting on this context
- @return collection of property names.
- """
- return self._props.get(PROP_CAN_SEARCH)
-
- def getRole(self):
- """
- Get the role the register plays in a program execution.
- @return role name.
- """
- return self._props.get(PROP_ROLE)
-
- def get(self, done):
- """
- Read value of the context.
- @param done - call back object.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def set(self, value, done):
- """
- Set value of the context.
- @param value - value to write into the context.
- @param done - call back object.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def search(self, filter, done):
- """
- Search register contexts that passes given search filter.
- Search is only supported for properties listed in the "CanSearch" property.
- @param filter - properties bag that defines search filter.
- @param done - call back object.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
-
-class RegistersService(services.Service):
- def getName(self):
- return NAME
-
- def getContext(self, id, done):
- """
- Retrieve context info for given context ID.
-
- @param id - context ID.
- @param done - call back interface called when operation is completed.
- """
- raise NotImplementedError("Abstract method")
-
- def getChildren(self, parent_context_id, done):
- """
- Retrieve contexts available for registers commands.
- A context corresponds to an execution thread, stack frame, registers group, etc.
- A context can belong to a parent context. Contexts hierarchy can be simple
- plain list or it can form a tree. It is up to target agent developers to choose
- layout that is most descriptive for a given target. Context IDs are valid across
- all services. In other words, all services access same hierarchy of contexts,
- with same IDs, however, each service accesses its own subset of context's
- attributes and functionality, which is relevant to that service.
-
- @param parent_context_id - parent context ID. Can be None -
- to retrieve top level of the hierarchy, or one of context IDs retrieved
- by previous getChildren commands.
- @param done - call back interface called when operation is completed.
- """
- raise NotImplementedError("Abstract method")
-
- def getm(self, locs, done):
- """
- Read values of multiple locations in registers.
- @param locs - array of data locations.
- @param done - call back object.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def setm(self, locs, value, done):
- """
- Set values of multiple locations in registers.
- @param locs - array of data locations.
- @param value - value to write into the context.
- @param done - call back object.
- @return - pending command handle.
- """
- raise NotImplementedError("Abstract method")
-
- def addListener(self, listener):
- """
- Add registers service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
- def removeListener(self, listener):
- """
- Remove registers service event listener.
- @param listener - event listener implementation.
- """
- raise NotImplementedError("Abstract method")
-
-
-class NamedValue(object):
- """
- A register context can have predefined names (mnemonics) for some its values.
- NamedValue objects represent such values.
- """
- def __init__(self, value, name, description):
- self.value = value
- self.name = name
- self.description = description
-
- def getValue(self):
- """
- Get value associated with the name.
- @return the value as an array of bytes.
- """
- return self.value
-
- def getName(self):
- """
- Get name (mnemonic) of the value.
- @return value name.
- """
- return self.name
-
- def getDescription(self):
- """
- Get human readable description of the value.
- @return value description.
- """
- return self.description
-
-class DoneGet(object):
- """
- 'get' command call back interface.
- """
- def doneGet(self, token, error, value):
- """
- Called when value retrieval is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- @param value - context value as array of bytes.
- """
- pass
-
-class DoneSet(object):
- """
- 'set' command call back interface.
- """
- def doneSet(self, token, error):
- """
- Called when value setting is done.
- @param token - command handle.
- @param error - error description if operation failed, None if succeeded.
- """
- pass
-
-class DoneSearch(object):
- """
- 'search' command call back interface.
- """
- def doneSearch(self, token, error, paths):
- """
- Called when context search is done.
- @param token - command handle.
- @param error - error description if operation failed, None if succeeded.
- @param paths - array of paths to each context with properties matching the filter
- """
- pass
-
-class DoneGetContext(object):
- def doneGetContext(self, token, error, context):
- """
- Called when context data retrieval is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- @param context - context data.
- """
- pass
-
-class DoneGetChildren(object):
- """
- Client call back interface for getChildren().
- """
- def doneGetChildren(self, token, error, context_ids):
- """
- Called when context list retrieval is done.
- @param token - command handle
- @param error - error description if operation failed, None if succeeded.
- @param context_ids - array of available context IDs.
- """
- pass
-
-
-class RegistersListener(object):
- """
- Registers event listener is notified when registers context hierarchy
- changes, and when a register is modified by the service commands.
- """
-
- def contextChanged(self):
- """
- Called when register context properties changed.
- Most targets have static set of registers and register properties.
- Such targets never generate this event. However, some targets,
- for example, JTAG probes, allow user to modify register definitions.
- Clients should flush all cached register context data.
- """
- pass
-
- def registerChanged(self, id):
- """
- Called when register content was changed and clients
- need to update themselves. Clients, at least, should invalidate
- corresponding cached registers data.
- Not every change is notified - it is not possible,
- only those, which are not caused by normal execution of the debuggee.
- At least, changes caused by "set" command should be notified.
- @param id - register context ID.
- """
- pass
-
-
-class Location(object):
- """
- Class Location represents value location in register context
- """
- def __init__(self, id, offs, size):
- # Register context ID
- self.id = id
- # offset in the context, in bytes
- self.offs = offs
- # value size in bytes
- self.size = size
- def __iter__(self):
- yield self.id
- yield self.offs
- yield self.size
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+Registers service provides access to target CPU register values and properties.
+"""
+
+from tcf import services
+
+NAME = "Registers"
+
+# Context property names.
+PROP_ID = "ID" # String, ID of the context
+PROP_PARENT_ID = "ParentID" # String, ID of a parent context
+PROP_PROCESS_ID = "ProcessID" # String, process ID
+PROP_NAME = "Name" # String, context name
+PROP_DESCRIPTION = "Description" # String, context description
+PROP_SIZE = "Size" # Number, context size in bytes. Byte arrays in get/set commands should be same size
+PROP_READBLE = "Readable" # Boolean, true if context value can be read
+PROP_READ_ONCE = "ReadOnce" # Boolean, true if reading the context (register) destroys its current value
+PROP_WRITEABLE = "Writeable" # Boolean, true if context value can be written
+PROP_WRITE_ONCE = "WriteOnce" # Boolean, true if register value can not be overwritten - every write counts
+PROP_SIDE_EFFECTS = "SideEffects" # Boolean, true if writing the context can change values of other registers
+PROP_VOLATILE = "Volatile" # Boolean, true if the register value can change even when target is stopped
+PROP_FLOAT = "Float" # Boolean, true if the register value is a floating-point value
+PROP_BIG_ENDIAN = "BigEndian" # Boolean, true if big endian
+PROP_LEFT_TO_RIGHT = "LeftToRight" # Boolean, true if the lowest numbered bit should be shown to user as the left-most bit
+PROP_FIST_BIT = "FirstBit" # Number, bit numbering base (0 or 1) to use when showing bits to user
+PROP_BITS = "Bits" # Number, if context is a bit field, contains the field bit numbers in the parent context
+PROP_VALUES = "Values" # Array of Map, predefined names (mnemonics) for some of context values
+PROP_MEMORY_ADDRESS = "MemoryAddress" # Number, the address of a memory mapped register
+PROP_MEMORY_CONTEXT = "MemoryContext" # String, the context ID of a memory context in which a memory mapped register is located
+PROP_CAN_SEARCH = "CanSearch" # Array of String, a list of attribute names which can be searched for starting on this context
+PROP_ROLE = "Role" # String, the role the register plays in a program execution
+
+# Values of context property "Role".
+ROLE_PC = "PC" # Program counter. Defines instruction to execute next
+ROLE_SP = "SP" # Register defining the current stack pointer location
+ROLE_FP = "FP" # Register defining the current frame pointer location
+ROLE_RET = "RET" # Register used to store the return address for calls
+ROLE_CORE = "CORE" # Indicates register or register groups which belong to the core state
+
+# Search filter properties.
+SEARCH_NAME = "Name" # The name of the property this filter applies too
+SEARCH_EQUAL_VALUE = "EqualValue" # The value which is searched for
+
+
+class RegistersContext(object):
+ """
+ RegistersContext objects represent register groups, registers and bit fields.
+ """
+ def __init__(self, props):
+ self._props = props or {}
+
+ def __str__(self):
+ return "[Registers Context %s]" % self._props
+
+ def getProperties(self):
+ """
+ Get context properties. See PROP_* definitions for property names.
+ Context properties are read only, clients should not try to modify them.
+ @return Map of context properties.
+ """
+ return self._props
+
+ def getID(self):
+ """
+ Get Context ID.
+ @return context ID.
+ """
+ return self._props.get(PROP_ID)
+
+ def getParentID(self):
+ """
+ Get parent context ID.
+ @return parent context ID.
+ """
+ return self._props.get(PROP_PARENT_ID)
+
+ def getProcessID(self):
+ """
+ Get process ID, if applicable.
+ @return process ID.
+ """
+ return self._props.get(PROP_PROCESS_ID)
+
+ def getName(self):
+ """
+ Get context (register, register group, bit field) name.
+ @return context name.
+ """
+ return self._props.get(PROP_NAME)
+
+ def getDescription(self):
+ """
+ Get context description.
+ @return context description.
+ """
+ return self._props.get(PROP_DESCRIPTION)
+
+ def getSize(self):
+ """
+ Get context size in bytes.
+ Byte arrays in get()/set() methods should be same size.
+ Hardware register can be smaller then this size, for example in case
+ when register size is not an even number of bytes. In such case implementation
+ should add/remove padding that consist of necessary number of zero bits.
+ @return context size in bytes.
+ """
+ return self._props.get(PROP_SIZE, 0)
+
+ def isReadable(self):
+ """
+ Check if context value can be read.
+ @return true if can read value of the context.
+ """
+ return self._props.get(PROP_READBLE)
+
+ def isReadOnce(self):
+ """
+ Check if reading the context (register) destroys its current value -
+ it can be read only once.
+ @return true if read-once register.
+ """
+ return self._props.get(PROP_READ_ONCE)
+
+ def isWriteable(self):
+ """
+ Check if context value can be written.
+ @return true if can write value of the context.
+ """
+ return self._props.get(PROP_WRITEABLE)
+
+ def isWriteOnce(self):
+ """
+ Check if register value can not be overwritten - every write counts.
+ @return true if write-once register.
+ """
+ return self._props.get(PROP_WRITE_ONCE)
+
+ def hasSideEffects(self):
+ """
+ Check if writing the context can change values of other registers.
+ @return true if has side effects.
+ """
+ return self._props.get(PROP_SIDE_EFFECTS)
+
+ def isVolatile(self):
+ """
+ Check if the register value can change even when target is stopped.
+ @return true if the register value can change at any time.
+ """
+ return self._props.get(PROP_VOLATILE)
+
+ def isFloat(self):
+ """
+ Check if the register value is a floating-point value.
+ @return true if a floating-point register.
+ """
+ return self._props.get(PROP_FLOAT)
+
+ def isBigEndian(self):
+ """
+ Check endianness of the context.
+ Big endian means decreasing numeric significance with increasing bit number.
+ The endianness is used to encode and decode values of get, getm, set and setm commands.
+ @return true if big endian.
+ """
+ return self._props.get(PROP_BIG_ENDIAN)
+
+ def isLeftToRight(self):
+ """
+ Check if the lowest numbered bit (i.e. bit #0 or bit #1 depending on
+ getFirstBitNumber() value) should be shown to user as the left-most bit or
+ the right-most bit.
+ @return true if the first bit is left-most bit.
+ """
+ return self._props.get(PROP_LEFT_TO_RIGHT)
+
+ def getFirstBitNumber(self):
+ """
+ If the context has bit field children, bit positions of the fields
+ can be zero-based or 1-based.
+ @return first bit position - 0 or 1.
+ """
+ return self._props.get(PROP_FIST_BIT, 0)
+
+ def getBitNumbers(self):
+ """
+ If context is a bit field, get the field bit numbers in parent context.
+ @return array of bit numbers.
+ """
+ return self._props.get(PROP_BITS)
+
+ def getNamedValues(self):
+ """
+ A context can have predefined names (mnemonics) for some its values.
+ This method returns a list of such named values.
+ @return array of named values or None.
+ """
+ return self._props.get(PROP_VALUES)
+
+ def getMemoryAddress(self):
+ """
+ Get the address of a memory mapped register.
+ @return address.
+ """
+ return self._props.get(PROP_MEMORY_ADDRESS)
+
+ def getMemoryContext(self):
+ """
+ Get the context ID of a memory context in which a memory mapped register is located.
+ @return memory context ID.
+ """
+ return self._props.get(PROP_MEMORY_CONTEXT)
+
+ def canSearch(self):
+ """
+ Get a list of property names which can be searched for starting on this context
+ @return collection of property names.
+ """
+ return self._props.get(PROP_CAN_SEARCH)
+
+ def getRole(self):
+ """
+ Get the role the register plays in a program execution.
+ @return role name.
+ """
+ return self._props.get(PROP_ROLE)
+
+ def get(self, done):
+ """
+ Read value of the context.
+ @param done - call back object.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def set(self, value, done):
+ """
+ Set value of the context.
+ @param value - value to write into the context.
+ @param done - call back object.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def search(self, filter, done):
+ """
+ Search register contexts that passes given search filter.
+ Search is only supported for properties listed in the "CanSearch" property.
+ @param filter - properties bag that defines search filter.
+ @param done - call back object.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+
+class RegistersService(services.Service):
+ def getName(self):
+ return NAME
+
+ def getContext(self, id, done):
+ """
+ Retrieve context info for given context ID.
+
+ @param id - context ID.
+ @param done - call back interface called when operation is completed.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getChildren(self, parent_context_id, done):
+ """
+ Retrieve contexts available for registers commands.
+ A context corresponds to an execution thread, stack frame, registers group, etc.
+ A context can belong to a parent context. Contexts hierarchy can be simple
+ plain list or it can form a tree. It is up to target agent developers to choose
+ layout that is most descriptive for a given target. Context IDs are valid across
+ all services. In other words, all services access same hierarchy of contexts,
+ with same IDs, however, each service accesses its own subset of context's
+ attributes and functionality, which is relevant to that service.
+
+ @param parent_context_id - parent context ID. Can be None -
+ to retrieve top level of the hierarchy, or one of context IDs retrieved
+ by previous getChildren commands.
+ @param done - call back interface called when operation is completed.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def getm(self, locs, done):
+ """
+ Read values of multiple locations in registers.
+ @param locs - array of data locations.
+ @param done - call back object.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def setm(self, locs, value, done):
+ """
+ Set values of multiple locations in registers.
+ @param locs - array of data locations.
+ @param value - value to write into the context.
+ @param done - call back object.
+ @return - pending command handle.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def addListener(self, listener):
+ """
+ Add registers service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+ def removeListener(self, listener):
+ """
+ Remove registers service event listener.
+ @param listener - event listener implementation.
+ """
+ raise NotImplementedError("Abstract method")
+
+
+class NamedValue(object):
+ """
+ A register context can have predefined names (mnemonics) for some its values.
+ NamedValue objects represent such values.
+ """
+ def __init__(self, value, name, description):
+ self.value = value
+ self.name = name
+ self.description = description
+
+ def getValue(self):
+ """
+ Get value associated with the name.
+ @return the value as an array of bytes.
+ """
+ return self.value
+
+ def getName(self):
+ """
+ Get name (mnemonic) of the value.
+ @return value name.
+ """
+ return self.name
+
+ def getDescription(self):
+ """
+ Get human readable description of the value.
+ @return value description.
+ """
+ return self.description
+
+class DoneGet(object):
+ """
+ 'get' command call back interface.
+ """
+ def doneGet(self, token, error, value):
+ """
+ Called when value retrieval is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ @param value - context value as array of bytes.
+ """
+ pass
+
+class DoneSet(object):
+ """
+ 'set' command call back interface.
+ """
+ def doneSet(self, token, error):
+ """
+ Called when value setting is done.
+ @param token - command handle.
+ @param error - error description if operation failed, None if succeeded.
+ """
+ pass
+
+class DoneSearch(object):
+ """
+ 'search' command call back interface.
+ """
+ def doneSearch(self, token, error, paths):
+ """
+ Called when context search is done.
+ @param token - command handle.
+ @param error - error description if operation failed, None if succeeded.
+ @param paths - array of paths to each context with properties matching the filter
+ """
+ pass
+
+class DoneGetContext(object):
+ def doneGetContext(self, token, error, context):
+ """
+ Called when context data retrieval is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ @param context - context data.
+ """
+ pass
+
+class DoneGetChildren(object):
+ """
+ Client call back interface for getChildren().
+ """
+ def doneGetChildren(self, token, error, context_ids):
+ """
+ Called when context list retrieval is done.
+ @param token - command handle
+ @param error - error description if operation failed, None if succeeded.
+ @param context_ids - array of available context IDs.
+ """
+ pass
+
+
+class RegistersListener(object):
+ """
+ Registers event listener is notified when registers context hierarchy
+ changes, and when a register is modified by the service commands.
+ """
+
+ def contextChanged(self):
+ """
+ Called when register context properties changed.
+ Most targets have static set of registers and register properties.
+ Such targets never generate this event. However, some targets,
+ for example, JTAG probes, allow user to modify register definitions.
+ Clients should flush all cached register context data.
+ """
+ pass
+
+ def registerChanged(self, id):
+ """
+ Called when register content was changed and clients
+ need to update themselves. Clients, at least, should invalidate
+ corresponding cached registers data.
+ Not every change is notified - it is not possible,
+ only those, which are not caused by normal execution of the debuggee.
+ At least, changes caused by "set" command should be notified.
+ @param id - register context ID.
+ """
+ pass
+
+
+class Location(object):
+ """
+ Class Location represents value location in register context
+ """
+ def __init__(self, id, offs, size):
+ # Register context ID
+ self.id = id
+ # offset in the context, in bytes
+ self.offs = offs
+ # value size in bytes
+ self.size = size
+ def __iter__(self):
+ yield self.id
+ yield self.offs
+ yield self.size
diff --git a/python/src/tcf/services/remote/BreakpointsProxy.py b/python/src/tcf/services/remote/BreakpointsProxy.py
index 7111c5a48..b7674a3b7 100644
--- a/python/src/tcf/services/remote/BreakpointsProxy.py
+++ b/python/src/tcf/services/remote/BreakpointsProxy.py
@@ -1,149 +1,149 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import channel
-from tcf.services import breakpoints
-from tcf.channel.Command import Command
-
-class BPCommand(Command):
- def __init__(self, service, cmd, cb, *args):
- super(BPCommand, self).__init__(service.channel, service, cmd, args)
- self.__cb = cb
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- self.__cb.doneCommand(self.token, error)
-
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "status":
- assert len(args) == 2
- self.listener.breakpointStatusChanged(args[0], args[1])
- elif name == "contextAdded":
- assert len(args) == 1
- self.listener.contextAdded(args[0])
- elif name == "contextChanged":
- assert len(args) == 1
- self.listener.contextChanged(args[0])
- elif name == "contextRemoved":
- assert len(args) == 1
- self.listener.contextRemoved(args[0])
- else:
- raise IOError("Breakpoints service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
-
-class BreakpointsProxy(breakpoints.BreakpointsService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def set(self, properties, done):
- done = self._makeCallback(done)
- return BPCommand(self, "set", done, properties).token
-
- def add(self, properties, done):
- done = self._makeCallback(done)
- return BPCommand(self, "add", done, properties).token
-
- def change(self, properties, done):
- done = self._makeCallback(done)
- return BPCommand(self, "change", done, properties).token
-
- def disable(self, ids, done):
- done = self._makeCallback(done)
- return BPCommand(self, "disable", done, ids).token
-
- def enable(self, ids, done):
- done = self._makeCallback(done)
- return BPCommand(self, "enable", done, ids).token
-
- def remove(self, ids, done):
- done = self._makeCallback(done)
- return BPCommand(self, "remove", done, ids).token
-
- def getIDs(self, done):
- done = self._makeCallback(done)
- service = self
- class GetIDsCommand(Command):
- def __init__(self):
- super(GetIDsCommand, self).__init__(service.channel, service, "getIDs", None)
- def done(self, error, args):
- ids = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- ids = args[1]
- done.doneGetIDs(self.token, error, ids)
- return GetIDsCommand().token
-
- def getProperties(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetPropertiesCommand(Command):
- def __init__(self):
- super(GetPropertiesCommand, self).__init__(service.channel, service, "getProperties", (id,))
- def done(self, error, args):
- map = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- map = args[1]
- done.doneGetProperties(self.token, error, map)
- return GetPropertiesCommand().token
-
- def getStatus(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetStatusCommand(Command):
- def __init__(self):
- super(GetStatusCommand, self).__init__(service.channel, service, "getStatus", (id,))
- def done(self, error, args):
- map = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- map = args[1]
- done.doneGetStatus(self.token, error, map)
- return GetStatusCommand().token
-
- def getCapabilities(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetCapabilitiesCommand(Command):
- def __init__(self):
- super(GetCapabilitiesCommand, self).__init__(service.channel, service, "getCapabilities", (id,))
- def done(self, error, args):
- map = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- map = args[1]
- done.doneGetCapabilities(self.token, error, map)
- return GetCapabilitiesCommand().token
-
- def addListener(self, listener):
- l = ChannelEventListener(self, listener)
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.get(listener)
- if l:
- del self.listeners[listener]
- self.channel.removeEventListener(self, l)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import channel
+from tcf.services import breakpoints
+from tcf.channel.Command import Command
+
+class BPCommand(Command):
+ def __init__(self, service, cmd, cb, *args):
+ super(BPCommand, self).__init__(service.channel, service, cmd, args)
+ self.__cb = cb
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ self.__cb.doneCommand(self.token, error)
+
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "status":
+ assert len(args) == 2
+ self.listener.breakpointStatusChanged(args[0], args[1])
+ elif name == "contextAdded":
+ assert len(args) == 1
+ self.listener.contextAdded(args[0])
+ elif name == "contextChanged":
+ assert len(args) == 1
+ self.listener.contextChanged(args[0])
+ elif name == "contextRemoved":
+ assert len(args) == 1
+ self.listener.contextRemoved(args[0])
+ else:
+ raise IOError("Breakpoints service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
+
+class BreakpointsProxy(breakpoints.BreakpointsService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def set(self, properties, done):
+ done = self._makeCallback(done)
+ return BPCommand(self, "set", done, properties).token
+
+ def add(self, properties, done):
+ done = self._makeCallback(done)
+ return BPCommand(self, "add", done, properties).token
+
+ def change(self, properties, done):
+ done = self._makeCallback(done)
+ return BPCommand(self, "change", done, properties).token
+
+ def disable(self, ids, done):
+ done = self._makeCallback(done)
+ return BPCommand(self, "disable", done, ids).token
+
+ def enable(self, ids, done):
+ done = self._makeCallback(done)
+ return BPCommand(self, "enable", done, ids).token
+
+ def remove(self, ids, done):
+ done = self._makeCallback(done)
+ return BPCommand(self, "remove", done, ids).token
+
+ def getIDs(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetIDsCommand(Command):
+ def __init__(self):
+ super(GetIDsCommand, self).__init__(service.channel, service, "getIDs", None)
+ def done(self, error, args):
+ ids = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ ids = args[1]
+ done.doneGetIDs(self.token, error, ids)
+ return GetIDsCommand().token
+
+ def getProperties(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetPropertiesCommand(Command):
+ def __init__(self):
+ super(GetPropertiesCommand, self).__init__(service.channel, service, "getProperties", (id,))
+ def done(self, error, args):
+ map = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ map = args[1]
+ done.doneGetProperties(self.token, error, map)
+ return GetPropertiesCommand().token
+
+ def getStatus(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetStatusCommand(Command):
+ def __init__(self):
+ super(GetStatusCommand, self).__init__(service.channel, service, "getStatus", (id,))
+ def done(self, error, args):
+ map = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ map = args[1]
+ done.doneGetStatus(self.token, error, map)
+ return GetStatusCommand().token
+
+ def getCapabilities(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetCapabilitiesCommand(Command):
+ def __init__(self):
+ super(GetCapabilitiesCommand, self).__init__(service.channel, service, "getCapabilities", (id,))
+ def done(self, error, args):
+ map = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ map = args[1]
+ done.doneGetCapabilities(self.token, error, map)
+ return GetCapabilitiesCommand().token
+
+ def addListener(self, listener):
+ l = ChannelEventListener(self, listener)
+ self.channel.addEventListener(self, l)
+ self.listeners[listener] = l
+
+ def removeListener(self, listener):
+ l = self.listeners.get(listener)
+ if l:
+ del self.listeners[listener]
+ self.channel.removeEventListener(self, l)
diff --git a/python/src/tcf/services/remote/DiagnosticsProxy.py b/python/src/tcf/services/remote/DiagnosticsProxy.py
index 24305a1ca..944533ab6 100644
--- a/python/src/tcf/services/remote/DiagnosticsProxy.py
+++ b/python/src/tcf/services/remote/DiagnosticsProxy.py
@@ -1,174 +1,174 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-import time
-from tcf import errors
-from tcf.services import diagnostics
-from tcf.channel.Command import Command
-
-class DiagnosticsProxy(diagnostics.DiagnosticsService):
- def __init__(self, channel):
- self.channel = channel
-
- def echo(self, s, done):
- done = self._makeCallback(done)
- service = self
- class EchoCommand(Command):
- def __init__(self):
- super(EchoCommand, self).__init__(service.channel, service, "echo", (s,))
- def done(self, error, args):
- str = None
- if not error:
- assert len(args) == 1
- str = args[0]
- done.doneEcho(self.token, error, str)
- return EchoCommand().token
-
- def echoFP(self, n, done):
- done = self._makeCallback(done)
- service = self
- class EchoFPCommand(Command):
- def __init__(self):
- super(EchoFPCommand, self).__init__(service.channel, service, "echoFP", (n,))
- def done(self, error, args):
- n = None
- if not error:
- assert len(args) == 1
- n = args[0]
- done.doneEchoFP(self.token, error, n)
- return EchoFPCommand().token
-
- def echoERR(self, err, done):
- map = None
- if isinstance(err, errors.ErrorReport):
- map = err.getAttributes()
- else:
- map = {
- errors.ERROR_TIME : int(time.time() * 1000),
- errors.ERROR_CODE : errors.TCF_ERROR_OTHER,
- errors.ERROR_FORMAT : err.message
- }
- done = self._makeCallback(done)
- service = self
- class EchoERRCommand(Command):
- def __init__(self):
- super(EchoERRCommand, self).__init__(service.channel, service, "echoERR", (map,))
- def done(self, error, args):
- err = None
- str = None
- if not error:
- assert len(args) == 2
- err = self.toError(args[0])
- str = args[1]
- done.doneEchoERR(self.token, error, err, str)
- return EchoERRCommand().token
-
- def getTestList(self, done):
- done = self._makeCallback(done)
- service = self
- class GetTestListCommand(Command):
- def __init__(self):
- super(GetTestListCommand, self).__init__(service.channel, service, "getTestList", None)
- def done(self, error, args):
- arr = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- arr = args[1]
- done.doneGetTestList(self.token, error, arr)
- return GetTestListCommand().token
-
- def runTest(self, s, done):
- done = self._makeCallback(done)
- service = self
- class RunTestCommand(Command):
- def __init__(self):
- super(RunTestCommand, self).__init__(service.channel, service, "runTest", (s,))
- def done(self, error, args):
- str = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- str = args[1]
- done.doneRunTest(self.token, error, str)
- return RunTestCommand().token
-
- def cancelTest(self, s, done):
- done = self._makeCallback(done)
- service = self
- class CancelTestCommand(Command):
- def __init__(self):
- super(CancelTestCommand, self).__init__(service.channel, service, "cancelTest", (s,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCancelTest(self.token, error)
- return CancelTestCommand().token
-
- def getSymbol(self, context_id, symbol_name, done):
- done = self._makeCallback(done)
- service = self
- class GetSymbolCommand(Command):
- def __init__(self):
- super(GetSymbolCommand, self).__init__(service.channel, service, "getSymbol", (context_id, symbol_name))
- def done(self, error, args):
- sym = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- sym = _toSymbol(args[1])
- done.doneGetSymbol(self.token, error, sym)
- return GetSymbolCommand().token
-
- def createTestStreams(self, inp_buf_size, out_buf_size, done):
- done = self._makeCallback(done)
- service = self
- class CreateTestStreamsCommand(Command):
- def __init__(self):
- super(CreateTestStreamsCommand, self).__init__(service.channel, service, "createTestStreams", (inp_buf_size, out_buf_size))
- def done(self, error, args):
- inp_id = None
- out_id = None
- if not error:
- assert len(args) == 3
- error = self.toError(args[0])
- inp_id = args[1]
- out_id = args[2]
- done.doneCreateTestStreams(self.token, error, inp_id, out_id)
- return CreateTestStreamsCommand().token
-
- def disposeTestStream(self, id, done):
- done = self._makeCallback(done)
- service = self
- class DisposeTestStreamCommand(Command):
- def __init__(self):
- super(DisposeTestStreamCommand, self).__init__(service.channel, service, "disposeTestStream", (id,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneDisposeTestStream(self.token, error)
- return DisposeTestStreamCommand().token
-
- def not_implemented_command(self, done):
- done = self._makeCallback(done)
- service = self
- class NotImplementedCommand(Command):
- def __init__(self):
- super(NotImplementedCommand, self).__init__(service.channel, service, "not implemented command", None)
- def done(self, error, args):
- done.doneNotImplementedCommand(self.token, error)
- return NotImplementedCommand().token
-
-def _toSymbol(o):
- if o is None: return None
- return diagnostics.Symbol(o)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+import time
+from tcf import errors
+from tcf.services import diagnostics
+from tcf.channel.Command import Command
+
+class DiagnosticsProxy(diagnostics.DiagnosticsService):
+ def __init__(self, channel):
+ self.channel = channel
+
+ def echo(self, s, done):
+ done = self._makeCallback(done)
+ service = self
+ class EchoCommand(Command):
+ def __init__(self):
+ super(EchoCommand, self).__init__(service.channel, service, "echo", (s,))
+ def done(self, error, args):
+ str = None
+ if not error:
+ assert len(args) == 1
+ str = args[0]
+ done.doneEcho(self.token, error, str)
+ return EchoCommand().token
+
+ def echoFP(self, n, done):
+ done = self._makeCallback(done)
+ service = self
+ class EchoFPCommand(Command):
+ def __init__(self):
+ super(EchoFPCommand, self).__init__(service.channel, service, "echoFP", (n,))
+ def done(self, error, args):
+ n = None
+ if not error:
+ assert len(args) == 1
+ n = args[0]
+ done.doneEchoFP(self.token, error, n)
+ return EchoFPCommand().token
+
+ def echoERR(self, err, done):
+ map = None
+ if isinstance(err, errors.ErrorReport):
+ map = err.getAttributes()
+ else:
+ map = {
+ errors.ERROR_TIME : int(time.time() * 1000),
+ errors.ERROR_CODE : errors.TCF_ERROR_OTHER,
+ errors.ERROR_FORMAT : err.message
+ }
+ done = self._makeCallback(done)
+ service = self
+ class EchoERRCommand(Command):
+ def __init__(self):
+ super(EchoERRCommand, self).__init__(service.channel, service, "echoERR", (map,))
+ def done(self, error, args):
+ err = None
+ str = None
+ if not error:
+ assert len(args) == 2
+ err = self.toError(args[0])
+ str = args[1]
+ done.doneEchoERR(self.token, error, err, str)
+ return EchoERRCommand().token
+
+ def getTestList(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetTestListCommand(Command):
+ def __init__(self):
+ super(GetTestListCommand, self).__init__(service.channel, service, "getTestList", None)
+ def done(self, error, args):
+ arr = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ arr = args[1]
+ done.doneGetTestList(self.token, error, arr)
+ return GetTestListCommand().token
+
+ def runTest(self, s, done):
+ done = self._makeCallback(done)
+ service = self
+ class RunTestCommand(Command):
+ def __init__(self):
+ super(RunTestCommand, self).__init__(service.channel, service, "runTest", (s,))
+ def done(self, error, args):
+ str = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ str = args[1]
+ done.doneRunTest(self.token, error, str)
+ return RunTestCommand().token
+
+ def cancelTest(self, s, done):
+ done = self._makeCallback(done)
+ service = self
+ class CancelTestCommand(Command):
+ def __init__(self):
+ super(CancelTestCommand, self).__init__(service.channel, service, "cancelTest", (s,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneCancelTest(self.token, error)
+ return CancelTestCommand().token
+
+ def getSymbol(self, context_id, symbol_name, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetSymbolCommand(Command):
+ def __init__(self):
+ super(GetSymbolCommand, self).__init__(service.channel, service, "getSymbol", (context_id, symbol_name))
+ def done(self, error, args):
+ sym = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ sym = _toSymbol(args[1])
+ done.doneGetSymbol(self.token, error, sym)
+ return GetSymbolCommand().token
+
+ def createTestStreams(self, inp_buf_size, out_buf_size, done):
+ done = self._makeCallback(done)
+ service = self
+ class CreateTestStreamsCommand(Command):
+ def __init__(self):
+ super(CreateTestStreamsCommand, self).__init__(service.channel, service, "createTestStreams", (inp_buf_size, out_buf_size))
+ def done(self, error, args):
+ inp_id = None
+ out_id = None
+ if not error:
+ assert len(args) == 3
+ error = self.toError(args[0])
+ inp_id = args[1]
+ out_id = args[2]
+ done.doneCreateTestStreams(self.token, error, inp_id, out_id)
+ return CreateTestStreamsCommand().token
+
+ def disposeTestStream(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class DisposeTestStreamCommand(Command):
+ def __init__(self):
+ super(DisposeTestStreamCommand, self).__init__(service.channel, service, "disposeTestStream", (id,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneDisposeTestStream(self.token, error)
+ return DisposeTestStreamCommand().token
+
+ def not_implemented_command(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class NotImplementedCommand(Command):
+ def __init__(self):
+ super(NotImplementedCommand, self).__init__(service.channel, service, "not implemented command", None)
+ def done(self, error, args):
+ done.doneNotImplementedCommand(self.token, error)
+ return NotImplementedCommand().token
+
+def _toSymbol(o):
+ if o is None: return None
+ return diagnostics.Symbol(o)
diff --git a/python/src/tcf/services/remote/DisassemblyProxy.py b/python/src/tcf/services/remote/DisassemblyProxy.py
index 0ef9bbb04..205f28d03 100644
--- a/python/src/tcf/services/remote/DisassemblyProxy.py
+++ b/python/src/tcf/services/remote/DisassemblyProxy.py
@@ -1,58 +1,58 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf.services import disassembly
-from tcf.channel.Command import Command
-
-class DisassemblyProxy(disassembly.DisassemblyService):
- def __init__(self, channel):
- self.channel = channel
-
- def getCapabilities(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetCapabilitiesCommand(Command):
- def __init__(self):
- super(GetCapabilitiesCommand, self).__init__(service.channel, service, "getCapabilities", (context_id,))
- def done(self, error, args):
- arr = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- arr = args[1]
- done.doneGetCapabilities(self.token, error, arr)
- return GetCapabilitiesCommand().token
-
- def disassemble(self, context_id, addr, size, params, done):
- done = self._makeCallback(done)
- service = self
- class DisassembleCommand(Command):
- def __init__(self):
- super(DisassembleCommand, self).__init__(service.channel, service, "disassemble", (context_id, addr, size, params))
- def done(self, error, args):
- arr = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- arr = _toDisassemblyArray(args[1])
- done.doneDisassemble(self.token, error, arr)
- return DisassembleCommand().token
-
-
-def _toDisassemblyArray(o):
- if o is None: return None
- return map(_toDisassemblyLine, o)
-
-def _toDisassemblyLine(m):
- addr = m.get("Address")
- size = m.get("Size")
- instruction = m.get("Instruction")
- return disassembly.DisassemblyLine(addr, size, instruction)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf.services import disassembly
+from tcf.channel.Command import Command
+
+class DisassemblyProxy(disassembly.DisassemblyService):
+ def __init__(self, channel):
+ self.channel = channel
+
+ def getCapabilities(self, context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetCapabilitiesCommand(Command):
+ def __init__(self):
+ super(GetCapabilitiesCommand, self).__init__(service.channel, service, "getCapabilities", (context_id,))
+ def done(self, error, args):
+ arr = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ arr = args[1]
+ done.doneGetCapabilities(self.token, error, arr)
+ return GetCapabilitiesCommand().token
+
+ def disassemble(self, context_id, addr, size, params, done):
+ done = self._makeCallback(done)
+ service = self
+ class DisassembleCommand(Command):
+ def __init__(self):
+ super(DisassembleCommand, self).__init__(service.channel, service, "disassemble", (context_id, addr, size, params))
+ def done(self, error, args):
+ arr = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ arr = _toDisassemblyArray(args[1])
+ done.doneDisassemble(self.token, error, arr)
+ return DisassembleCommand().token
+
+
+def _toDisassemblyArray(o):
+ if o is None: return None
+ return map(_toDisassemblyLine, o)
+
+def _toDisassemblyLine(m):
+ addr = m.get("Address")
+ size = m.get("Size")
+ instruction = m.get("Instruction")
+ return disassembly.DisassemblyLine(addr, size, instruction)
diff --git a/python/src/tcf/services/remote/ExpressionsProxy.py b/python/src/tcf/services/remote/ExpressionsProxy.py
index 462756f3c..f8dfa8179 100644
--- a/python/src/tcf/services/remote/ExpressionsProxy.py
+++ b/python/src/tcf/services/remote/ExpressionsProxy.py
@@ -1,134 +1,134 @@
-# *******************************************************************************
-# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import channel
-from tcf.services import expressions
-from tcf.channel.Command import Command
-
-class ExpressionsProxy(expressions.ExpressionsService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def assign(self, id, value, done):
- done = self._makeCallback(done)
- service = self
- value = bytearray(value)
- class AssignCommand(Command):
- def __init__(self):
- super(AssignCommand, self).__init__(service.channel, service, "assign", (id, value))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneAssign(self.token, error)
- return AssignCommand().token
-
- def create(self, parent_id, language, expression, done):
- done = self._makeCallback(done)
- service = self
- class CreateCommand(Command):
- def __init__(self):
- super(CreateCommand, self).__init__(service.channel, service, "create", (parent_id, language, expression))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- ctx = expressions.Expression(args[1])
- done.doneCreate(self.token, error, ctx)
- return CreateCommand().token
-
- def dispose(self, id, done):
- done = self._makeCallback(done)
- service = self
- class DisposeCommand(Command):
- def __init__(self):
- super(DisposeCommand, self).__init__(service.channel, service, "dispose", (id,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneDispose(self.token, error)
- return DisposeCommand().token
-
- def evaluate(self, id, done):
- done = self._makeCallback(done)
- service = self
- class EvalCommand(Command):
- def __init__(self):
- super(EvalCommand, self).__init__(service.channel, service, "evaluate", (id,))
- def done(self, error, args):
- value = None
- if not error:
- assert len(args) == 3
- value = channel.toByteArray(args[0])
- error = self.toError(args[1])
- props = args[2]
- done.doneEvaluate(self.token, error, expressions.Value(value, props))
- return EvalCommand().token
-
- def getChildren(self, parent_context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
- def getContext(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = expressions.Expression(service, args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def addListener(self, listener):
- l = ChannelEventListener(self, listener)
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.get(listener)
- if l:
- del self.listeners[listener]
- self.channel.removeEventListener(self, l)
-
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "valueChanged":
- assert len(args) == 1
- self.listener.valueChanged(args[0])
- else:
- raise IOError("Expressions service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
+# *******************************************************************************
+# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import channel
+from tcf.services import expressions
+from tcf.channel.Command import Command
+
+class ExpressionsProxy(expressions.ExpressionsService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def assign(self, id, value, done):
+ done = self._makeCallback(done)
+ service = self
+ value = bytearray(value)
+ class AssignCommand(Command):
+ def __init__(self):
+ super(AssignCommand, self).__init__(service.channel, service, "assign", (id, value))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneAssign(self.token, error)
+ return AssignCommand().token
+
+ def create(self, parent_id, language, expression, done):
+ done = self._makeCallback(done)
+ service = self
+ class CreateCommand(Command):
+ def __init__(self):
+ super(CreateCommand, self).__init__(service.channel, service, "create", (parent_id, language, expression))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ ctx = expressions.Expression(args[1])
+ done.doneCreate(self.token, error, ctx)
+ return CreateCommand().token
+
+ def dispose(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class DisposeCommand(Command):
+ def __init__(self):
+ super(DisposeCommand, self).__init__(service.channel, service, "dispose", (id,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneDispose(self.token, error)
+ return DisposeCommand().token
+
+ def evaluate(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class EvalCommand(Command):
+ def __init__(self):
+ super(EvalCommand, self).__init__(service.channel, service, "evaluate", (id,))
+ def done(self, error, args):
+ value = None
+ if not error:
+ assert len(args) == 3
+ value = channel.toByteArray(args[0])
+ error = self.toError(args[1])
+ props = args[2]
+ done.doneEvaluate(self.token, error, expressions.Value(value, props))
+ return EvalCommand().token
+
+ def getChildren(self, parent_context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+ def getContext(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = expressions.Expression(service, args[1])
+ done.doneGetContext(self.token, error, ctx)
+ return GetContextCommand().token
+
+ def addListener(self, listener):
+ l = ChannelEventListener(self, listener)
+ self.channel.addEventListener(self, l)
+ self.listeners[listener] = l
+
+ def removeListener(self, listener):
+ l = self.listeners.get(listener)
+ if l:
+ del self.listeners[listener]
+ self.channel.removeEventListener(self, l)
+
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "valueChanged":
+ assert len(args) == 1
+ self.listener.valueChanged(args[0])
+ else:
+ raise IOError("Expressions service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
diff --git a/python/src/tcf/services/remote/FileSystemProxy.py b/python/src/tcf/services/remote/FileSystemProxy.py
index d0a274642..370625f69 100644
--- a/python/src/tcf/services/remote/FileSystemProxy.py
+++ b/python/src/tcf/services/remote/FileSystemProxy.py
@@ -1,509 +1,509 @@
-# *******************************************************************************
-# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import errors, channel
-from tcf.services import filesystem
-from tcf.channel.Command import Command
-
-class Status(filesystem.FileSystemException):
- def __init__(self, status_or_exception, message=None, attrs=None):
- if isinstance(status_or_exception, int):
- super(Status, self).__init__(message)
- self.status = status_or_exception
- self.attrs = attrs
- else:
- super(Status, self).__init__(status_or_exception)
- self.status = errors.TCF_ERROR_OTHER
- self.attrs = {}
-
- def getStatus(self):
- return self.status
-
- def getErrorCode(self):
- return self.attrs.get(errors.ERROR_CODE, 0)
-
- def getAltCode(self):
- return self.attrs.get(errors.ERROR_ALT_CODE, 0)
-
- def getAltOrg(self):
- return self.attrs.get(errors.ERROR_ALT_ORG)
-
- def getAttributes(self):
- return self.attrs
-
-class FileSystemCommand(Command):
- def __init__(self, service, command, args):
- super(FileSystemCommand, self).__init__(service.channel, service, command, args)
-
- def _toSFError(self, data):
- if data is None: return None
- error_code = map.get(errors.ERROR_CODE)
- cmd = self.getCommandString()
- if len(cmd) > 72: cmd = cmd[0, 72] + "..."
- s = Status(error_code,
- "TCF command exception:" +
- "\nCommand: " + cmd +
- "\nException: " + self.toErrorString(data) +
- "\nError code: " + error_code, map)
- caused_by = map.get(errors.ERROR_CAUSED_BY)
- if caused_by is not None: s.initCause(self.toError(caused_by, False))
- return s
-
-class FileSystemProxy(filesystem.FileSystemService):
- def __init__(self, channel):
- self.channel = channel
-
- def close(self, handle, done):
- assert handle.getService() is self
- done = self._makeCallback(done)
- id = handle.id
- service = self
- class CloseCommand(FileSystemCommand):
- def __init__(self):
- super(CloseCommand, self).__init__(service, "close", (id,))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneClose(self.token, s)
- return CloseCommand().token
-
- def setstat(self, path, attrs, done):
- done = self._makeCallback(done)
- dt = _toObject(attrs)
- service = self
- class SetStatCommand(FileSystemCommand):
- def __init__(self):
- super(SetStatCommand, self).__init__(service, "setstat", (path, dt))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneSetStat(self.token, s)
- return SetStatCommand().token
-
- def fsetstat(self, handle, attrs, done):
- done = self._makeCallback(done)
- assert handle.getService() is self
- id = handle.id
- dt = _toObject(attrs)
- service = self
- class FSetStatCommand(FileSystemCommand):
- def __init__(self):
- super(FSetStatCommand, self).__init__(service, "fsetstat", (id, dt))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneSetStat(self.token, s)
- return FSetStatCommand().token
-
- def stat(self, path, done):
- done = self._makeCallback(done)
- service = self
- class StatCommand(FileSystemCommand):
- def __init__(self):
- super(StatCommand, self).__init__(service, "stat", (path,))
- def done(self, error, args):
- s = None
- a = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[0])
- if not s: a = _toFileAttrs(args[1])
- done.doneStat(self.token, s, a)
- return StatCommand().token
-
- def fstat(self, handle, done):
- done = self._makeCallback(done)
- assert handle.getService() is self
- id = handle.id
- service = self
- class FStatCommand(FileSystemCommand):
- def __init__(self):
- super(FStatCommand, self).__init__(service, "fstat", (id,))
- def done(self, error, args):
- s = None
- a = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[0])
- if not s: a = _toFileAttrs(args[1])
- done.doneStat(self.token, s, a)
- return FStatCommand().token
-
- def lstat(self, path, done):
- done = self._makeCallback(done)
- service = self
- class LStatCommand(FileSystemCommand):
- def __init__(self):
- super(LStatCommand, self).__init__(service, "lstat", (path,))
- def done(self, error, args):
- s = None
- a = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[0])
- if not s: a = _toFileAttrs(args[1])
- done.doneStat(self.token, s, a)
- return LStatCommand().token
-
- def mkdir(self, path, attrs, done):
- done = self._makeCallback(done)
- dt = _toObject(attrs)
- service = self
- class MkDirCommand(FileSystemCommand):
- def __init__(self):
- super(MkDirCommand, self).__init__(service, "mkdir", (dt,))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneMkDir(self.token, s)
- return MkDirCommand().token
-
- def open(self, file_name, flags, attrs, done):
- done = self._makeCallback(done)
- dt = _toObject(attrs)
- service = self
- class OpenCommand(FileSystemCommand):
- def __init__(self):
- super(OpenCommand, self).__init__(service, "open", (file_name, flags, dt))
- def done(self, error, args):
- s = None
- h = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[0])
- if not s: h = service._toFileHandle(args[1])
- done.doneOpen(self.token, s, h)
- return OpenCommand().token
-
- def opendir(self, path, done):
- done = self._makeCallback(done)
- service = self
- class OpenDirCommand(FileSystemCommand):
- def __init__(self):
- super(OpenDirCommand, self).__init__(service, "opendir", (path,))
- def done(self, error, args):
- s = None
- h = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[0])
- if not s: h = service._toFileHandle(args[1])
- done.doneOpen(self.token, s, h)
- return OpenDirCommand().token
-
- def read(self, handle, offset, len, done):
- assert handle.getService() is self
- done = self._makeCallback(done)
- id = handle.id
- service = self
- class ReadCommand(FileSystemCommand):
- def __init__(self):
- super(ReadCommand, self).__init__(service, "read", (id, offset, len))
- def done(self, error, args):
- s = None
- b = None
- eof = False
- if error:
- s = Status(error)
- else:
- assert len(args) == 3
- s = self._toSFError(args[1])
- if not s:
- b = channel.toByteArray(args[0])
- eof = args[2]
- done.doneRead(self.token, s, b, eof)
- return ReadCommand().token
-
- def readdir(self, handle, done):
- assert handle.getService() is self
- done = self._makeCallback(done)
- id = handle.id
- service = self
- class ReadDirCommand(FileSystemCommand):
- def __init__(self):
- super(ReadDirCommand, self).__init__(service, "readdir", (id,))
- def done(self, error, args):
- s = None
- b = None
- eof = False
- if error:
- s = Status(error)
- else:
- assert len(args) == 3
- s = self._toSFError(args[1])
- if not s:
- b = _toDirEntryArray(args[0])
- eof = args[2]
- done.doneReadDir(self.token, s, b, eof)
- return ReadDirCommand().token
-
- def roots(self, done):
- done = self._makeCallback(done)
- service = self
- class RootCommand(FileSystemCommand):
- def __init__(self):
- super(RootCommand, self).__init__(service, "roots", None)
- def done(self, error, args):
- s = None
- b = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[1])
- if not s:
- b = _toDirEntryArray(args[0])
- done.doneRoots(self.token, s, b)
- return RootCommand().token
-
- def readlink(self, path, done):
- done = self._makeCallback(done)
- service = self
- class ReadLinkCommand(FileSystemCommand):
- def __init__(self):
- super(ReadLinkCommand, self).__init__(service, "readlink", (path,))
- def done(self, error, args):
- s = None
- p = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[0])
- if not s:
- p = args[1]
- done.doneReadLink(self.token, s, p)
- return ReadLinkCommand().token
-
- def realpath(self, path, done):
- done = self._makeCallback(done)
- service = self
- class RealPathCommand(FileSystemCommand):
- def __init__(self):
- super(RealPathCommand, self).__init__(service, "realpath", (path,))
- def done(self, error, args):
- s = None
- p = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 2
- s = self._toSFError(args[0])
- if not s:
- p = args[1]
- done.doneRealPath(self.token, s, p)
- return RealPathCommand().token
-
- def remove(self, file_name, done):
- done = self._makeCallback(done)
- service = self
- class RemoveCommand(FileSystemCommand):
- def __init__(self):
- super(RemoveCommand, self).__init__(service, "remove", (file_name,))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneRemove(self.token, s)
- return RemoveCommand().token
-
- def rename(self, old_path, new_path, done):
- done = self._makeCallback(done)
- service = self
- class RenameCommand(FileSystemCommand):
- def __init__(self):
- super(RenameCommand, self).__init__(service, "rename", (old_path, new_path))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneRename(self.token, s)
- return RenameCommand().token
-
- def rmdir(self, path, done):
- done = self._makeCallback(done)
- service = self
- class RmDirCommand(FileSystemCommand):
- def __init__(self):
- super(RmDirCommand, self).__init__(service, "rmdir", (path,))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneRemove(self.token, s)
- return RmDirCommand().token
-
- def symlink(self, link_path, target_path, done):
- done = self._makeCallback(done)
- service = self
- class SymLinkCommand(FileSystemCommand):
- def __init__(self):
- super(SymLinkCommand, self).__init__(service, "symlink", (link_path, target_path))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneSymLink(self.token, s)
- return SymLinkCommand().token
-
- def write(self, handle, offset, data, data_pos, data_size, done):
- assert handle.getService() is self
- done = self._makeCallback(done)
- id = handle.id
- binary = bytearray(data[data_pos:data_pos+data_size])
- service = self
- class WriteCommand(FileSystemCommand):
- def __init__(self):
- super(WriteCommand, self).__init__(service, "write", (id, offset, binary))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneWrite(self.token, s)
- return WriteCommand().token
-
- def copy(self, src_path, dst_path, copy_permissions, copy_uidgid, done):
- done = self._makeCallback(done)
- service = self
- class CopyCommand(FileSystemCommand):
- def __init__(self):
- super(CopyCommand, self).__init__(service, "copy",
- (id, src_path, dst_path, copy_permissions, copy_uidgid))
- def done(self, error, args):
- s = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 1
- s = self._toSFError(args[0])
- done.doneCopy(self.token, s)
- return CopyCommand().token
-
- def user(self, done):
- done = self._makeCallback(done)
- service = self
- class UserCommand(FileSystemCommand):
- def __init__(self):
- super(UserCommand, self).__init__(service, "user", None)
- def done(self, error, args):
- s = None
- r_uid = 0
- e_uid = 0
- r_gid = 0
- e_gid = 0
- home = None
- if error:
- s = Status(error)
- else:
- assert len(args) == 5
- r_uid, e_uid, r_gid, e_gid, home = args
- done.doneUser(self.token, s, r_uid, e_uid, r_gid, e_gid, home)
- return UserCommand().token
-
- def _toFileHandle(self, o):
- if o is None: return None
- return filesystem.FileHandle(self, o)
-
-def _toObject(attrs):
- if attrs is None: return None
- m = {}
- if attrs.attributes is not None: m.update(attrs.attributes)
- if (attrs.flags & filesystem.ATTR_SIZE) != 0:
- m["Size"] = attrs.size
- if (attrs.flags & filesystem.ATTR_UIDGID) != 0:
- m["UID"] = attrs.uid
- m["GID"] = attrs.gid
- if (attrs.flags & filesystem.ATTR_PERMISSIONS) != 0:
- m["Permissions"] = attrs.permissions
- if (attrs.flags & filesystem.ATTR_ACMODTIME) != 0:
- m["ATime"] = attrs.atime
- m["MTime"] = attrs.mtime
- return m
-
-def _toFileAttrs(m):
- if m is None: return None
- flags = 0
- size = 0
- uid = 0
- gid = 0
- permissions = 0
- atime = 0
- mtime = 0
- n = m.pop("Size", None)
- if n is not None:
- size = n
- flags |= filesystem.ATTR_SIZE
- n1 = m.pop("UID", None)
- n2 = m.pop("GID", None)
- if n1 is not None and n2 is not None:
- uid = n1
- gid = n2
- flags |= filesystem.ATTR_UIDGID
- n = m.pop("Permissions", None)
- if n is not None:
- permissions = n
- flags |= filesystem.ATTR_PERMISSIONS
- n1 = m.pop("ATime", None)
- n2 = m.pop("MTime", None)
- if n1 is not None and n2 is not None:
- atime = n1
- mtime = n2
- flags |= filesystem.ATTR_ACMODTIME
- return filesystem.FileAttrs(flags, size, uid, gid, permissions, atime, mtime, m)
-
-def _toDirEntryArray(o):
- if o is None: return None
- res = []
- for m in o:
- entry = filesystem.DirEntry(m.get("FileName"), m.get("LongName"), _toFileAttrs(m.get("Attrs")))
- res.append(entry)
- return res
+# *******************************************************************************
+# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import errors, channel
+from tcf.services import filesystem
+from tcf.channel.Command import Command
+
+class Status(filesystem.FileSystemException):
+ def __init__(self, status_or_exception, message=None, attrs=None):
+ if isinstance(status_or_exception, int):
+ super(Status, self).__init__(message)
+ self.status = status_or_exception
+ self.attrs = attrs
+ else:
+ super(Status, self).__init__(status_or_exception)
+ self.status = errors.TCF_ERROR_OTHER
+ self.attrs = {}
+
+ def getStatus(self):
+ return self.status
+
+ def getErrorCode(self):
+ return self.attrs.get(errors.ERROR_CODE, 0)
+
+ def getAltCode(self):
+ return self.attrs.get(errors.ERROR_ALT_CODE, 0)
+
+ def getAltOrg(self):
+ return self.attrs.get(errors.ERROR_ALT_ORG)
+
+ def getAttributes(self):
+ return self.attrs
+
+class FileSystemCommand(Command):
+ def __init__(self, service, command, args):
+ super(FileSystemCommand, self).__init__(service.channel, service, command, args)
+
+ def _toSFError(self, data):
+ if data is None: return None
+ error_code = map.get(errors.ERROR_CODE)
+ cmd = self.getCommandString()
+ if len(cmd) > 72: cmd = cmd[0, 72] + "..."
+ s = Status(error_code,
+ "TCF command exception:" +
+ "\nCommand: " + cmd +
+ "\nException: " + self.toErrorString(data) +
+ "\nError code: " + error_code, map)
+ caused_by = map.get(errors.ERROR_CAUSED_BY)
+ if caused_by is not None: s.initCause(self.toError(caused_by, False))
+ return s
+
+class FileSystemProxy(filesystem.FileSystemService):
+ def __init__(self, channel):
+ self.channel = channel
+
+ def close(self, handle, done):
+ assert handle.getService() is self
+ done = self._makeCallback(done)
+ id = handle.id
+ service = self
+ class CloseCommand(FileSystemCommand):
+ def __init__(self):
+ super(CloseCommand, self).__init__(service, "close", (id,))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneClose(self.token, s)
+ return CloseCommand().token
+
+ def setstat(self, path, attrs, done):
+ done = self._makeCallback(done)
+ dt = _toObject(attrs)
+ service = self
+ class SetStatCommand(FileSystemCommand):
+ def __init__(self):
+ super(SetStatCommand, self).__init__(service, "setstat", (path, dt))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneSetStat(self.token, s)
+ return SetStatCommand().token
+
+ def fsetstat(self, handle, attrs, done):
+ done = self._makeCallback(done)
+ assert handle.getService() is self
+ id = handle.id
+ dt = _toObject(attrs)
+ service = self
+ class FSetStatCommand(FileSystemCommand):
+ def __init__(self):
+ super(FSetStatCommand, self).__init__(service, "fsetstat", (id, dt))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneSetStat(self.token, s)
+ return FSetStatCommand().token
+
+ def stat(self, path, done):
+ done = self._makeCallback(done)
+ service = self
+ class StatCommand(FileSystemCommand):
+ def __init__(self):
+ super(StatCommand, self).__init__(service, "stat", (path,))
+ def done(self, error, args):
+ s = None
+ a = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[0])
+ if not s: a = _toFileAttrs(args[1])
+ done.doneStat(self.token, s, a)
+ return StatCommand().token
+
+ def fstat(self, handle, done):
+ done = self._makeCallback(done)
+ assert handle.getService() is self
+ id = handle.id
+ service = self
+ class FStatCommand(FileSystemCommand):
+ def __init__(self):
+ super(FStatCommand, self).__init__(service, "fstat", (id,))
+ def done(self, error, args):
+ s = None
+ a = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[0])
+ if not s: a = _toFileAttrs(args[1])
+ done.doneStat(self.token, s, a)
+ return FStatCommand().token
+
+ def lstat(self, path, done):
+ done = self._makeCallback(done)
+ service = self
+ class LStatCommand(FileSystemCommand):
+ def __init__(self):
+ super(LStatCommand, self).__init__(service, "lstat", (path,))
+ def done(self, error, args):
+ s = None
+ a = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[0])
+ if not s: a = _toFileAttrs(args[1])
+ done.doneStat(self.token, s, a)
+ return LStatCommand().token
+
+ def mkdir(self, path, attrs, done):
+ done = self._makeCallback(done)
+ dt = _toObject(attrs)
+ service = self
+ class MkDirCommand(FileSystemCommand):
+ def __init__(self):
+ super(MkDirCommand, self).__init__(service, "mkdir", (dt,))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneMkDir(self.token, s)
+ return MkDirCommand().token
+
+ def open(self, file_name, flags, attrs, done):
+ done = self._makeCallback(done)
+ dt = _toObject(attrs)
+ service = self
+ class OpenCommand(FileSystemCommand):
+ def __init__(self):
+ super(OpenCommand, self).__init__(service, "open", (file_name, flags, dt))
+ def done(self, error, args):
+ s = None
+ h = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[0])
+ if not s: h = service._toFileHandle(args[1])
+ done.doneOpen(self.token, s, h)
+ return OpenCommand().token
+
+ def opendir(self, path, done):
+ done = self._makeCallback(done)
+ service = self
+ class OpenDirCommand(FileSystemCommand):
+ def __init__(self):
+ super(OpenDirCommand, self).__init__(service, "opendir", (path,))
+ def done(self, error, args):
+ s = None
+ h = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[0])
+ if not s: h = service._toFileHandle(args[1])
+ done.doneOpen(self.token, s, h)
+ return OpenDirCommand().token
+
+ def read(self, handle, offset, len, done):
+ assert handle.getService() is self
+ done = self._makeCallback(done)
+ id = handle.id
+ service = self
+ class ReadCommand(FileSystemCommand):
+ def __init__(self):
+ super(ReadCommand, self).__init__(service, "read", (id, offset, len))
+ def done(self, error, args):
+ s = None
+ b = None
+ eof = False
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 3
+ s = self._toSFError(args[1])
+ if not s:
+ b = channel.toByteArray(args[0])
+ eof = args[2]
+ done.doneRead(self.token, s, b, eof)
+ return ReadCommand().token
+
+ def readdir(self, handle, done):
+ assert handle.getService() is self
+ done = self._makeCallback(done)
+ id = handle.id
+ service = self
+ class ReadDirCommand(FileSystemCommand):
+ def __init__(self):
+ super(ReadDirCommand, self).__init__(service, "readdir", (id,))
+ def done(self, error, args):
+ s = None
+ b = None
+ eof = False
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 3
+ s = self._toSFError(args[1])
+ if not s:
+ b = _toDirEntryArray(args[0])
+ eof = args[2]
+ done.doneReadDir(self.token, s, b, eof)
+ return ReadDirCommand().token
+
+ def roots(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class RootCommand(FileSystemCommand):
+ def __init__(self):
+ super(RootCommand, self).__init__(service, "roots", None)
+ def done(self, error, args):
+ s = None
+ b = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[1])
+ if not s:
+ b = _toDirEntryArray(args[0])
+ done.doneRoots(self.token, s, b)
+ return RootCommand().token
+
+ def readlink(self, path, done):
+ done = self._makeCallback(done)
+ service = self
+ class ReadLinkCommand(FileSystemCommand):
+ def __init__(self):
+ super(ReadLinkCommand, self).__init__(service, "readlink", (path,))
+ def done(self, error, args):
+ s = None
+ p = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[0])
+ if not s:
+ p = args[1]
+ done.doneReadLink(self.token, s, p)
+ return ReadLinkCommand().token
+
+ def realpath(self, path, done):
+ done = self._makeCallback(done)
+ service = self
+ class RealPathCommand(FileSystemCommand):
+ def __init__(self):
+ super(RealPathCommand, self).__init__(service, "realpath", (path,))
+ def done(self, error, args):
+ s = None
+ p = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 2
+ s = self._toSFError(args[0])
+ if not s:
+ p = args[1]
+ done.doneRealPath(self.token, s, p)
+ return RealPathCommand().token
+
+ def remove(self, file_name, done):
+ done = self._makeCallback(done)
+ service = self
+ class RemoveCommand(FileSystemCommand):
+ def __init__(self):
+ super(RemoveCommand, self).__init__(service, "remove", (file_name,))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneRemove(self.token, s)
+ return RemoveCommand().token
+
+ def rename(self, old_path, new_path, done):
+ done = self._makeCallback(done)
+ service = self
+ class RenameCommand(FileSystemCommand):
+ def __init__(self):
+ super(RenameCommand, self).__init__(service, "rename", (old_path, new_path))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneRename(self.token, s)
+ return RenameCommand().token
+
+ def rmdir(self, path, done):
+ done = self._makeCallback(done)
+ service = self
+ class RmDirCommand(FileSystemCommand):
+ def __init__(self):
+ super(RmDirCommand, self).__init__(service, "rmdir", (path,))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneRemove(self.token, s)
+ return RmDirCommand().token
+
+ def symlink(self, link_path, target_path, done):
+ done = self._makeCallback(done)
+ service = self
+ class SymLinkCommand(FileSystemCommand):
+ def __init__(self):
+ super(SymLinkCommand, self).__init__(service, "symlink", (link_path, target_path))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneSymLink(self.token, s)
+ return SymLinkCommand().token
+
+ def write(self, handle, offset, data, data_pos, data_size, done):
+ assert handle.getService() is self
+ done = self._makeCallback(done)
+ id = handle.id
+ binary = bytearray(data[data_pos:data_pos+data_size])
+ service = self
+ class WriteCommand(FileSystemCommand):
+ def __init__(self):
+ super(WriteCommand, self).__init__(service, "write", (id, offset, binary))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneWrite(self.token, s)
+ return WriteCommand().token
+
+ def copy(self, src_path, dst_path, copy_permissions, copy_uidgid, done):
+ done = self._makeCallback(done)
+ service = self
+ class CopyCommand(FileSystemCommand):
+ def __init__(self):
+ super(CopyCommand, self).__init__(service, "copy",
+ (id, src_path, dst_path, copy_permissions, copy_uidgid))
+ def done(self, error, args):
+ s = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 1
+ s = self._toSFError(args[0])
+ done.doneCopy(self.token, s)
+ return CopyCommand().token
+
+ def user(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class UserCommand(FileSystemCommand):
+ def __init__(self):
+ super(UserCommand, self).__init__(service, "user", None)
+ def done(self, error, args):
+ s = None
+ r_uid = 0
+ e_uid = 0
+ r_gid = 0
+ e_gid = 0
+ home = None
+ if error:
+ s = Status(error)
+ else:
+ assert len(args) == 5
+ r_uid, e_uid, r_gid, e_gid, home = args
+ done.doneUser(self.token, s, r_uid, e_uid, r_gid, e_gid, home)
+ return UserCommand().token
+
+ def _toFileHandle(self, o):
+ if o is None: return None
+ return filesystem.FileHandle(self, o)
+
+def _toObject(attrs):
+ if attrs is None: return None
+ m = {}
+ if attrs.attributes is not None: m.update(attrs.attributes)
+ if (attrs.flags & filesystem.ATTR_SIZE) != 0:
+ m["Size"] = attrs.size
+ if (attrs.flags & filesystem.ATTR_UIDGID) != 0:
+ m["UID"] = attrs.uid
+ m["GID"] = attrs.gid
+ if (attrs.flags & filesystem.ATTR_PERMISSIONS) != 0:
+ m["Permissions"] = attrs.permissions
+ if (attrs.flags & filesystem.ATTR_ACMODTIME) != 0:
+ m["ATime"] = attrs.atime
+ m["MTime"] = attrs.mtime
+ return m
+
+def _toFileAttrs(m):
+ if m is None: return None
+ flags = 0
+ size = 0
+ uid = 0
+ gid = 0
+ permissions = 0
+ atime = 0
+ mtime = 0
+ n = m.pop("Size", None)
+ if n is not None:
+ size = n
+ flags |= filesystem.ATTR_SIZE
+ n1 = m.pop("UID", None)
+ n2 = m.pop("GID", None)
+ if n1 is not None and n2 is not None:
+ uid = n1
+ gid = n2
+ flags |= filesystem.ATTR_UIDGID
+ n = m.pop("Permissions", None)
+ if n is not None:
+ permissions = n
+ flags |= filesystem.ATTR_PERMISSIONS
+ n1 = m.pop("ATime", None)
+ n2 = m.pop("MTime", None)
+ if n1 is not None and n2 is not None:
+ atime = n1
+ mtime = n2
+ flags |= filesystem.ATTR_ACMODTIME
+ return filesystem.FileAttrs(flags, size, uid, gid, permissions, atime, mtime, m)
+
+def _toDirEntryArray(o):
+ if o is None: return None
+ res = []
+ for m in o:
+ entry = filesystem.DirEntry(m.get("FileName"), m.get("LongName"), _toFileAttrs(m.get("Attrs")))
+ res.append(entry)
+ return res
diff --git a/python/src/tcf/services/remote/LineNumbersProxy.py b/python/src/tcf/services/remote/LineNumbersProxy.py
index ad567d225..7452cc761 100644
--- a/python/src/tcf/services/remote/LineNumbersProxy.py
+++ b/python/src/tcf/services/remote/LineNumbersProxy.py
@@ -1,67 +1,67 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf.services import linenumbers
-from tcf.channel.Command import Command
-
-class LineNumbersProxy(linenumbers.LineNumbersService):
-
- def __init__(self, channel):
- self.channel = channel
-
- def mapToSource(self, context_id, start_address, end_address, done):
- done = self._makeCallback(done)
- service = self
- class MapCommand(Command):
- def __init__(self):
- super(MapCommand, self).__init__(service.channel, service,
- "mapToSource", (context_id, start_address, end_address))
- def done(self, error, args):
- arr = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- arr = _toCodeAreaArray(args[1])
- done.doneMapToSource(self.token, error, arr)
- return MapCommand().token
-
- def mapToMemory(self, context_id, file, line, column, done):
- done = self._makeCallback(done)
- service = self
- class MapCommand(Command):
- def __init__(self):
- super(MapCommand, self).__init__(service.channel, service,
- "mapToMemory", (context_id, file, line, column))
- def done(self, error, args):
- arr = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- arr = _toCodeAreaArray(args[1])
- done.doneMapToMemory(self.token, error, arr)
- return MapCommand().token
-
-def _toCodeAreaArray(o):
- if not o: return None
- arr = []
- directory = None
- file = None
- for area in o:
- directory = area.get("Dir", directory)
- file = area.get("File", file)
- arr.append(linenumbers.CodeArea(directory, file,
- area.get("SLine", 0), area.get("SCol", 0),
- area.get("ELine", 0), area.get("ECol", 0),
- area.get("SAddr"), area.get("EAddr"),
- area.get("ISA", 0),
- area.get("IsStmt"), area.get("BasicBlock"),
- area.get("PrologueEnd"), area.get("EpilogueBegin")))
- return arr
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf.services import linenumbers
+from tcf.channel.Command import Command
+
+class LineNumbersProxy(linenumbers.LineNumbersService):
+
+ def __init__(self, channel):
+ self.channel = channel
+
+ def mapToSource(self, context_id, start_address, end_address, done):
+ done = self._makeCallback(done)
+ service = self
+ class MapCommand(Command):
+ def __init__(self):
+ super(MapCommand, self).__init__(service.channel, service,
+ "mapToSource", (context_id, start_address, end_address))
+ def done(self, error, args):
+ arr = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ arr = _toCodeAreaArray(args[1])
+ done.doneMapToSource(self.token, error, arr)
+ return MapCommand().token
+
+ def mapToMemory(self, context_id, file, line, column, done):
+ done = self._makeCallback(done)
+ service = self
+ class MapCommand(Command):
+ def __init__(self):
+ super(MapCommand, self).__init__(service.channel, service,
+ "mapToMemory", (context_id, file, line, column))
+ def done(self, error, args):
+ arr = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ arr = _toCodeAreaArray(args[1])
+ done.doneMapToMemory(self.token, error, arr)
+ return MapCommand().token
+
+def _toCodeAreaArray(o):
+ if not o: return None
+ arr = []
+ directory = None
+ file = None
+ for area in o:
+ directory = area.get("Dir", directory)
+ file = area.get("File", file)
+ arr.append(linenumbers.CodeArea(directory, file,
+ area.get("SLine", 0), area.get("SCol", 0),
+ area.get("ELine", 0), area.get("ECol", 0),
+ area.get("SAddr"), area.get("EAddr"),
+ area.get("ISA", 0),
+ area.get("IsStmt"), area.get("BasicBlock"),
+ area.get("PrologueEnd"), area.get("EpilogueBegin")))
+ return arr
diff --git a/python/src/tcf/services/remote/LocatorProxy.py b/python/src/tcf/services/remote/LocatorProxy.py
index 8072118c1..d9963686e 100644
--- a/python/src/tcf/services/remote/LocatorProxy.py
+++ b/python/src/tcf/services/remote/LocatorProxy.py
@@ -1,149 +1,149 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import protocol, peer, channel
-from tcf.services import locator
-from tcf.channel.Command import Command
-
-class Peer(peer.TransientPeer):
- def __init__(self, parent, attrs):
- super(Peer, self).__init__(attrs)
- self.parent = parent
- def openChannel(self):
- assert protocol.isDispatchThread()
- c = self.parent.openChannel()
- c.redirect(self.getID())
- return c
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, proxy):
- self.proxy = proxy
- self.channel = proxy.channel
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "peerAdded":
- assert len(args) == 1
- _peer = Peer(self.channel.getRemotePeer(), args[0])
- if self.proxy.peers.get(_peer.getID()):
- protocol.log("Invalid peerAdded event", Exception())
- return
- self.proxy.peers[_peer.getID()] = _peer
- for l in self.proxy.listeners:
- try:
- l.peerAdded(_peer)
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- elif name == "peerChanged":
- assert len(args) == 1
- m = args[0]
- if not m: raise Exception("Locator service: invalid peerChanged event - no peer ID")
- _peer = self.proxy.peers.get(m.get(peer.ATTR_ID))
- if not _peer: return
- self.proxy.peers[_peer.getID()] = _peer
- for l in self.proxy.listeners:
- try:
- l.peerChanged(_peer)
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- elif name == "peerRemoved":
- assert len(args) == 1
- id = args[0]
- _peer = self.proxy.peers.get(id)
- if not _peer: return
- del self.proxy.peers[id]
- for l in self.proxy.listeners:
- try:
- l.peerRemoved(id)
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- elif name == "peerHeartBeat":
- assert len(args) == 1
- id = args[0]
- _peer = self.proxy.peers.get(id)
- if not _peer: return
- for l in self.proxy.listeners:
- try:
- l.peerHeartBeat(id)
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- else:
- raise IOError("Locator service: unknown event: " + name)
- except Exception as x:
- self.channel.terminate(x)
-
-class LocatorProxy(locator.LocatorService):
- def __init__(self, channel):
- self.channel = channel;
- self.peers = {}
- self.listeners = []
- self.get_peers_done = False
- self.event_listener = ChannelEventListener(self)
- channel.addEventListener(self, self.event_listener)
-
- def getPeers(self):
- return self.peers
-
- def redirect(self, _peer, done):
- done = self._makeCallback(done)
- service = self
- class RedirectCommand(Command):
- def __init__(self):
- super(RedirectCommand, self).__init__(service.channel, service, "redirect", [_peer])
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneRedirect(self.token, error)
- return RedirectCommand().token
-
- def sync(self, done):
- done = self._makeCallback(done)
- service = self
- class SyncCommand(Command):
- def __init__(self):
- super(SyncCommand, self).__init__(service.channel, service, "sync", None)
- def done(self, error, args):
- if error: service.channel.terminate(error)
- done.doneSync(self.token)
- return SyncCommand().token
-
- def addListener(self, listener):
- self.listeners.append(listener)
- if not self.get_peers_done:
- service = self
- class GetPeersCommand(Command):
- def __init__(self):
- super(GetPeersCommand, self).__init__(service.channel, service, "getPeers", None)
- def done(self, error, args):
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if error:
- protocol.log("Locator error", error)
- return
- c = args[1]
- if c:
- for m in c:
- id = m.get(peer.ATTR_ID)
- if service.peers.get(id): continue;
- _peer = Peer(service.channel.getRemotePeer(), m)
- service.peers[id] = _peer
- for l in service.listeners:
- try:
- l.peerAdded(_peer)
- except Exception as x:
- protocol.log("Unhandled exception in Locator listener", x)
- GetPeersCommand()
- self.get_peers_done = True
-
- def removeListener(self, listener):
- self.listeners.remove(listener)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import protocol, peer, channel
+from tcf.services import locator
+from tcf.channel.Command import Command
+
+class Peer(peer.TransientPeer):
+ def __init__(self, parent, attrs):
+ super(Peer, self).__init__(attrs)
+ self.parent = parent
+ def openChannel(self):
+ assert protocol.isDispatchThread()
+ c = self.parent.openChannel()
+ c.redirect(self.getID())
+ return c
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, proxy):
+ self.proxy = proxy
+ self.channel = proxy.channel
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "peerAdded":
+ assert len(args) == 1
+ _peer = Peer(self.channel.getRemotePeer(), args[0])
+ if self.proxy.peers.get(_peer.getID()):
+ protocol.log("Invalid peerAdded event", Exception())
+ return
+ self.proxy.peers[_peer.getID()] = _peer
+ for l in self.proxy.listeners:
+ try:
+ l.peerAdded(_peer)
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ elif name == "peerChanged":
+ assert len(args) == 1
+ m = args[0]
+ if not m: raise Exception("Locator service: invalid peerChanged event - no peer ID")
+ _peer = self.proxy.peers.get(m.get(peer.ATTR_ID))
+ if not _peer: return
+ self.proxy.peers[_peer.getID()] = _peer
+ for l in self.proxy.listeners:
+ try:
+ l.peerChanged(_peer)
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ elif name == "peerRemoved":
+ assert len(args) == 1
+ id = args[0]
+ _peer = self.proxy.peers.get(id)
+ if not _peer: return
+ del self.proxy.peers[id]
+ for l in self.proxy.listeners:
+ try:
+ l.peerRemoved(id)
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ elif name == "peerHeartBeat":
+ assert len(args) == 1
+ id = args[0]
+ _peer = self.proxy.peers.get(id)
+ if not _peer: return
+ for l in self.proxy.listeners:
+ try:
+ l.peerHeartBeat(id)
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ else:
+ raise IOError("Locator service: unknown event: " + name)
+ except Exception as x:
+ self.channel.terminate(x)
+
+class LocatorProxy(locator.LocatorService):
+ def __init__(self, channel):
+ self.channel = channel;
+ self.peers = {}
+ self.listeners = []
+ self.get_peers_done = False
+ self.event_listener = ChannelEventListener(self)
+ channel.addEventListener(self, self.event_listener)
+
+ def getPeers(self):
+ return self.peers
+
+ def redirect(self, _peer, done):
+ done = self._makeCallback(done)
+ service = self
+ class RedirectCommand(Command):
+ def __init__(self):
+ super(RedirectCommand, self).__init__(service.channel, service, "redirect", [_peer])
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneRedirect(self.token, error)
+ return RedirectCommand().token
+
+ def sync(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class SyncCommand(Command):
+ def __init__(self):
+ super(SyncCommand, self).__init__(service.channel, service, "sync", None)
+ def done(self, error, args):
+ if error: service.channel.terminate(error)
+ done.doneSync(self.token)
+ return SyncCommand().token
+
+ def addListener(self, listener):
+ self.listeners.append(listener)
+ if not self.get_peers_done:
+ service = self
+ class GetPeersCommand(Command):
+ def __init__(self):
+ super(GetPeersCommand, self).__init__(service.channel, service, "getPeers", None)
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if error:
+ protocol.log("Locator error", error)
+ return
+ c = args[1]
+ if c:
+ for m in c:
+ id = m.get(peer.ATTR_ID)
+ if service.peers.get(id): continue;
+ _peer = Peer(service.channel.getRemotePeer(), m)
+ service.peers[id] = _peer
+ for l in service.listeners:
+ try:
+ l.peerAdded(_peer)
+ except Exception as x:
+ protocol.log("Unhandled exception in Locator listener", x)
+ GetPeersCommand()
+ self.get_peers_done = True
+
+ def removeListener(self, listener):
+ self.listeners.remove(listener)
diff --git a/python/src/tcf/services/remote/MemoryMapProxy.py b/python/src/tcf/services/remote/MemoryMapProxy.py
index 8bf153bac..34aab1d5f 100644
--- a/python/src/tcf/services/remote/MemoryMapProxy.py
+++ b/python/src/tcf/services/remote/MemoryMapProxy.py
@@ -1,82 +1,82 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import channel
-from tcf.services import memorymap
-from tcf.channel.Command import Command
-
-class MemoryMapProxy(memorymap.MemoryMapService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def get(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetCommand(Command):
- def __init__(self):
- super(GetCommand, self).__init__(service.channel, service, "get", (id,))
- def done(self, error, args):
- map = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: map = _toMemoryMap(args[1])
- done.doneGet(self.token, error, map)
- return GetCommand().token
-
- def set(self, id, map, done):
- if isinstance(map, memorymap.MemoryRegion) or isinstance(map, dict):
- map = (map,)
- done = self._makeCallback(done)
- service = self
- class SetCommand(Command):
- def __init__(self):
- super(SetCommand, self).__init__(service.channel, service, "set", (id, map))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneSet(self.token, error)
- return SetCommand().token
-
- def addListener(self, listener):
- l = ChannelEventListener(self, listener)
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.pop(listener, None)
- if l: self.channel.removeEventListener(self, l)
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "changed":
- assert len(args) == 1
- self.listener.changed(args[0])
- else:
- raise IOError("MemoryMap service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
-
-
-def _toMemoryMap(o):
- if o is None: return None
- return map(_toMemoryRegion, o)
-
-def _toMemoryRegion(o):
- if o is None: return None
- return memorymap.MemoryRegion(o)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import channel
+from tcf.services import memorymap
+from tcf.channel.Command import Command
+
+class MemoryMapProxy(memorymap.MemoryMapService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def get(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetCommand(Command):
+ def __init__(self):
+ super(GetCommand, self).__init__(service.channel, service, "get", (id,))
+ def done(self, error, args):
+ map = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: map = _toMemoryMap(args[1])
+ done.doneGet(self.token, error, map)
+ return GetCommand().token
+
+ def set(self, id, map, done):
+ if isinstance(map, memorymap.MemoryRegion) or isinstance(map, dict):
+ map = (map,)
+ done = self._makeCallback(done)
+ service = self
+ class SetCommand(Command):
+ def __init__(self):
+ super(SetCommand, self).__init__(service.channel, service, "set", (id, map))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneSet(self.token, error)
+ return SetCommand().token
+
+ def addListener(self, listener):
+ l = ChannelEventListener(self, listener)
+ self.channel.addEventListener(self, l)
+ self.listeners[listener] = l
+
+ def removeListener(self, listener):
+ l = self.listeners.pop(listener, None)
+ if l: self.channel.removeEventListener(self, l)
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "changed":
+ assert len(args) == 1
+ self.listener.changed(args[0])
+ else:
+ raise IOError("MemoryMap service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
+
+
+def _toMemoryMap(o):
+ if o is None: return None
+ return map(_toMemoryRegion, o)
+
+def _toMemoryRegion(o):
+ if o is None: return None
+ return memorymap.MemoryRegion(o)
diff --git a/python/src/tcf/services/remote/MemoryProxy.py b/python/src/tcf/services/remote/MemoryProxy.py
index ebf8a2420..62f01bdcf 100644
--- a/python/src/tcf/services/remote/MemoryProxy.py
+++ b/python/src/tcf/services/remote/MemoryProxy.py
@@ -1,242 +1,242 @@
-# *******************************************************************************
-# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import errors, channel
-from tcf.services import memory
-from tcf.channel.Command import Command
-
-class Range(object):
- offs = 0
- size = 0
- stat = 0
- msg = None
- def __cmp__(self, o):
- if self.offs < o.offs: return -1
- if self.offs > o.offs: return +1
- return 0
-
-class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, memory.ErrorOffset):
- def __init__(self, msg, attrs, addr, ranges):
- super(MemoryErrorReport, self).__init__(msg, attrs)
- if ranges is None:
- self.ranges = None
- else:
- self.ranges = []
- for m in ranges:
- r = Range()
- x = m.get(memory.ErrorOffset.RANGE_KEY_ADDR)
- if isinstance(x, str):
- y = int(x)
- else:
- y = x
- r.offs = y - addr
- r.size = m.get(memory.ErrorOffset.RANGE_KEY_SIZE)
- r.stat = m.get(memory.ErrorOffset.RANGE_KEY_STAT)
- r.msg = errors.toErrorString(m.get(memory.ErrorOffset.RANGE_KEY_MSG))
- assert r.offs >= 0
- assert r.size >= 0
- self.ranges.append(r)
- self.ranges.sort()
-
- def getMessage(self, offset):
- if self.ranges is None: return None
- l = 0
- h = len(self.ranges) - 1
- while l <= h:
- n = (l + h) / 2
- r = self.ranges[n]
- if r.offs > offset:
- h = n - 1
- elif offset >= r.offs + r.size:
- l = n + 1
- else:
- return r.msg
- return None
-
- def getStatus(self, offset):
- if self.ranges is None: return memory.ErrorOffset.BYTE_UNKNOWN
- l = 0
- h = len(self.ranges) - 1
- while l <= h:
- n = (l + h) / 2
- r = self.ranges[n]
- if r.offs > offset:
- h = n - 1
- elif offset >= r.offs + r.size:
- l = n + 1
- else:
- return r.stat
- return memory.ErrorOffset.BYTE_UNKNOWN
-
-
-class MemContext(memory.MemoryContext):
- def __init__(self, service, props):
- super(MemContext, self).__init__(props)
- self.service = service
-
- def fill(self, addr, word_size, value, size, mode, done):
- service = self.service
- id = self.getID()
- done = service._makeCallback(done)
- class FillCommand(MemoryCommand):
- def __init__(self):
- super(FillCommand, self).__init__(service,
- "fill", (id, addr, word_size, size, mode, value))
- def done(self, error, args):
- e = None
- if error:
- e = memory.MemoryError(error.message)
- else:
- assert len(args) == 2
- e = self.toMemoryError(args[0], args[1])
- done.doneMemory(self.token, e)
- return FillCommand().token
-
- def get(self, addr, word_size, buf, offs, size, mode, done):
- service = self.service
- id = self.getID()
- done = service._makeCallback(done)
- class GetCommand(MemoryCommand):
- def __init__(self):
- super(GetCommand, self).__init__(service,
- "get", (id, addr, word_size, size, mode))
- def done(self, error, args):
- e = None
- if error:
- e = memory.MemoryError(error.message)
- else:
- assert len(args) == 3
- bytes = channel.toByteArray(args[0])
- assert len(bytes) <= size
- buf[offs:offs+len(bytes)] = bytes
- e = self.toMemoryError(args[1], args[2])
- done.doneMemory(self.token, e)
- return GetCommand().token
-
- def set(self, addr, word_size, buf, offs, size, mode, done):
- service = self.service
- id = self.getID()
- done = service._makeCallback(done)
- class SetCommand(MemoryCommand):
- def __init__(self):
- super(SetCommand, self).__init__(service,
- "set", (id, addr, word_size, size, mode, bytearray(buf[offs:offs:size])))
- def done(self, error, args):
- e = None
- if error:
- e = memory.MemoryError(error.message)
- else:
- assert len(args) == 2
- e = self.toMemoryError(args[1], args[2])
- done.doneMemory(self.token, e)
- return SetCommand().token
-
-class MemoryProxy(memory.MemoryService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def getContext(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = MemContext(service, args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def getChildren(self, parent_context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
- def addListener(self, listener):
- l = ChannelEventListener(self, listener)
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.get(listener)
- if l:
- del self.listeners[listener]
- self.channel.removeEventListener(self, l)
-
-class MemoryCommand(Command):
- def __init__(self, service, cmd, args):
- super(MemoryCommand, self).__init__(service.channel, service, cmd, args)
- def toMemoryError(self, addr, data, ranges):
- if data is None: return None
- code = data.get(errors.ERROR_CODE)
- cmd = self.getCommandString()
- if len(cmd) > 72: cmd = cmd[0:72] + "..."
- e = MemoryErrorReport(
- "TCF command exception:\nCommand: %s\nException: %s\nError code: " % (
- cmd, self.toErrorString(data), code),
- map, addr, ranges)
- caused_by = data.get(errors.ERROR_CAUSED_BY)
- if caused_by is not None: e.caused_by = self.toError(caused_by, False)
- return e
-
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "contextAdded":
- assert len(args) == 1
- self.listener.contextAdded(_toContextArray(self.service, args[0]))
- elif name == "contextChanged":
- assert len(args) == 1
- self.listener.contextChanged(_toContextArray(self.service, args[0]))
- elif name == "contextRemoved":
- assert len(args) == 1
- self.listener.contextRemoved(args[0])
- elif name == "memoryChanged":
- assert len(args) == 2
- self.listener.memoryChanged(args[0], _toAddrArray(args[1]), _toSizeArray(args[1]))
- else:
- raise IOError("Memory service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
-
-
-def _toContextArray(svc, o):
- if o is None: return None
- ctx = []
- for m in o: ctx.append(MemContext(svc, m))
- return ctx
-
-def _toSizeArray(o):
- if o is None: return None
- return map(lambda m: m.get("size", 0), o)
-
-def _toAddrArray(o):
- if o is None: return None
- return map(lambda m: m.get("addr"), o)
+# *******************************************************************************
+# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import errors, channel
+from tcf.services import memory
+from tcf.channel.Command import Command
+
+class Range(object):
+ offs = 0
+ size = 0
+ stat = 0
+ msg = None
+ def __cmp__(self, o):
+ if self.offs < o.offs: return -1
+ if self.offs > o.offs: return +1
+ return 0
+
+class MemoryErrorReport(errors.ErrorReport, memory.MemoryError, memory.ErrorOffset):
+ def __init__(self, msg, attrs, addr, ranges):
+ super(MemoryErrorReport, self).__init__(msg, attrs)
+ if ranges is None:
+ self.ranges = None
+ else:
+ self.ranges = []
+ for m in ranges:
+ r = Range()
+ x = m.get(memory.ErrorOffset.RANGE_KEY_ADDR)
+ if isinstance(x, str):
+ y = int(x)
+ else:
+ y = x
+ r.offs = y - addr
+ r.size = m.get(memory.ErrorOffset.RANGE_KEY_SIZE)
+ r.stat = m.get(memory.ErrorOffset.RANGE_KEY_STAT)
+ r.msg = errors.toErrorString(m.get(memory.ErrorOffset.RANGE_KEY_MSG))
+ assert r.offs >= 0
+ assert r.size >= 0
+ self.ranges.append(r)
+ self.ranges.sort()
+
+ def getMessage(self, offset):
+ if self.ranges is None: return None
+ l = 0
+ h = len(self.ranges) - 1
+ while l <= h:
+ n = (l + h) / 2
+ r = self.ranges[n]
+ if r.offs > offset:
+ h = n - 1
+ elif offset >= r.offs + r.size:
+ l = n + 1
+ else:
+ return r.msg
+ return None
+
+ def getStatus(self, offset):
+ if self.ranges is None: return memory.ErrorOffset.BYTE_UNKNOWN
+ l = 0
+ h = len(self.ranges) - 1
+ while l <= h:
+ n = (l + h) / 2
+ r = self.ranges[n]
+ if r.offs > offset:
+ h = n - 1
+ elif offset >= r.offs + r.size:
+ l = n + 1
+ else:
+ return r.stat
+ return memory.ErrorOffset.BYTE_UNKNOWN
+
+
+class MemContext(memory.MemoryContext):
+ def __init__(self, service, props):
+ super(MemContext, self).__init__(props)
+ self.service = service
+
+ def fill(self, addr, word_size, value, size, mode, done):
+ service = self.service
+ id = self.getID()
+ done = service._makeCallback(done)
+ class FillCommand(MemoryCommand):
+ def __init__(self):
+ super(FillCommand, self).__init__(service,
+ "fill", (id, addr, word_size, size, mode, value))
+ def done(self, error, args):
+ e = None
+ if error:
+ e = memory.MemoryError(error.message)
+ else:
+ assert len(args) == 2
+ e = self.toMemoryError(args[0], args[1])
+ done.doneMemory(self.token, e)
+ return FillCommand().token
+
+ def get(self, addr, word_size, buf, offs, size, mode, done):
+ service = self.service
+ id = self.getID()
+ done = service._makeCallback(done)
+ class GetCommand(MemoryCommand):
+ def __init__(self):
+ super(GetCommand, self).__init__(service,
+ "get", (id, addr, word_size, size, mode))
+ def done(self, error, args):
+ e = None
+ if error:
+ e = memory.MemoryError(error.message)
+ else:
+ assert len(args) == 3
+ bytes = channel.toByteArray(args[0])
+ assert len(bytes) <= size
+ buf[offs:offs+len(bytes)] = bytes
+ e = self.toMemoryError(args[1], args[2])
+ done.doneMemory(self.token, e)
+ return GetCommand().token
+
+ def set(self, addr, word_size, buf, offs, size, mode, done):
+ service = self.service
+ id = self.getID()
+ done = service._makeCallback(done)
+ class SetCommand(MemoryCommand):
+ def __init__(self):
+ super(SetCommand, self).__init__(service,
+ "set", (id, addr, word_size, size, mode, bytearray(buf[offs:offs:size])))
+ def done(self, error, args):
+ e = None
+ if error:
+ e = memory.MemoryError(error.message)
+ else:
+ assert len(args) == 2
+ e = self.toMemoryError(args[1], args[2])
+ done.doneMemory(self.token, e)
+ return SetCommand().token
+
+class MemoryProxy(memory.MemoryService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def getContext(self, context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = MemContext(service, args[1])
+ done.doneGetContext(self.token, error, ctx)
+ return GetContextCommand().token
+
+ def getChildren(self, parent_context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+ def addListener(self, listener):
+ l = ChannelEventListener(self, listener)
+ self.channel.addEventListener(self, l)
+ self.listeners[listener] = l
+
+ def removeListener(self, listener):
+ l = self.listeners.get(listener)
+ if l:
+ del self.listeners[listener]
+ self.channel.removeEventListener(self, l)
+
+class MemoryCommand(Command):
+ def __init__(self, service, cmd, args):
+ super(MemoryCommand, self).__init__(service.channel, service, cmd, args)
+ def toMemoryError(self, addr, data, ranges):
+ if data is None: return None
+ code = data.get(errors.ERROR_CODE)
+ cmd = self.getCommandString()
+ if len(cmd) > 72: cmd = cmd[0:72] + "..."
+ e = MemoryErrorReport(
+ "TCF command exception:\nCommand: %s\nException: %s\nError code: " % (
+ cmd, self.toErrorString(data), code),
+ map, addr, ranges)
+ caused_by = data.get(errors.ERROR_CAUSED_BY)
+ if caused_by is not None: e.caused_by = self.toError(caused_by, False)
+ return e
+
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "contextAdded":
+ assert len(args) == 1
+ self.listener.contextAdded(_toContextArray(self.service, args[0]))
+ elif name == "contextChanged":
+ assert len(args) == 1
+ self.listener.contextChanged(_toContextArray(self.service, args[0]))
+ elif name == "contextRemoved":
+ assert len(args) == 1
+ self.listener.contextRemoved(args[0])
+ elif name == "memoryChanged":
+ assert len(args) == 2
+ self.listener.memoryChanged(args[0], _toAddrArray(args[1]), _toSizeArray(args[1]))
+ else:
+ raise IOError("Memory service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
+
+
+def _toContextArray(svc, o):
+ if o is None: return None
+ ctx = []
+ for m in o: ctx.append(MemContext(svc, m))
+ return ctx
+
+def _toSizeArray(o):
+ if o is None: return None
+ return map(lambda m: m.get("size", 0), o)
+
+def _toAddrArray(o):
+ if o is None: return None
+ return map(lambda m: m.get("addr"), o)
diff --git a/python/src/tcf/services/remote/PathMapProxy.py b/python/src/tcf/services/remote/PathMapProxy.py
index 93e8c07b8..770e972f9 100644
--- a/python/src/tcf/services/remote/PathMapProxy.py
+++ b/python/src/tcf/services/remote/PathMapProxy.py
@@ -1,56 +1,56 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf.services import pathmap
-from tcf.channel.Command import Command
-
-class PathMapProxy(pathmap.PathMapService):
- def __init__(self, channel):
- self.channel = channel
-
- def get(self, done):
- done = self._makeCallback(done)
- service = self
- class GetCommand(Command):
- def __init__(self):
- super(GetCommand, self).__init__(service.channel, service, "get", None)
- def done(self, error, args):
- map = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: map = _toPathMap(args[1])
- done.doneGet(self.token, error, map)
- return GetCommand().token
-
- def set(self, map, done):
- if isinstance(map, pathmap.PathMapRule) or isinstance(map, dict):
- map = (map,)
- done = self._makeCallback(done)
- service = self
- class SetCommand(Command):
- def __init__(self):
- super(SetCommand, self).__init__(service.channel, service, "set", (map,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneSet(self.token, error)
- return SetCommand().token
-
-
-def _toPathMap(o):
- if o is None: return None
- return map(_toPathMapRule, o)
-
-def _toPathMapRule(o):
- if o is None: return None
- return pathmap.PathMapRule(o)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf.services import pathmap
+from tcf.channel.Command import Command
+
+class PathMapProxy(pathmap.PathMapService):
+ def __init__(self, channel):
+ self.channel = channel
+
+ def get(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetCommand(Command):
+ def __init__(self):
+ super(GetCommand, self).__init__(service.channel, service, "get", None)
+ def done(self, error, args):
+ map = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: map = _toPathMap(args[1])
+ done.doneGet(self.token, error, map)
+ return GetCommand().token
+
+ def set(self, map, done):
+ if isinstance(map, pathmap.PathMapRule) or isinstance(map, dict):
+ map = (map,)
+ done = self._makeCallback(done)
+ service = self
+ class SetCommand(Command):
+ def __init__(self):
+ super(SetCommand, self).__init__(service.channel, service, "set", (map,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneSet(self.token, error)
+ return SetCommand().token
+
+
+def _toPathMap(o):
+ if o is None: return None
+ return map(_toPathMapRule, o)
+
+def _toPathMapRule(o):
+ if o is None: return None
+ return pathmap.PathMapRule(o)
diff --git a/python/src/tcf/services/remote/ProcessesProxy.py b/python/src/tcf/services/remote/ProcessesProxy.py
index 4e1dff2c6..9cfdcbd56 100644
--- a/python/src/tcf/services/remote/ProcessesProxy.py
+++ b/python/src/tcf/services/remote/ProcessesProxy.py
@@ -1,215 +1,215 @@
-# *******************************************************************************
-# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import channel
-from tcf.services import processes
-from tcf.channel.Command import Command
-
-class ProcessContext(processes.ProcessContext):
- def __init__(self, service, props):
- super(ProcessContext, self).__init__(props)
- self.service = service
-
- def attach(self, done):
- return self._command("attach", done)
-
- def detach(self, done):
- return self._command("detach", done)
-
- def terminate(self, done):
- return self._command("terminate", done)
-
- def _command(self, command, done):
- service = self.service
- done = service._makeCallback(done)
- id = self.getID()
- class _Command(Command):
- def __init__(self):
- super(_Command, self).__init__(service.channel, service,
- command, (id,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCommand(self.token, error)
- return _Command().token
-
-class ProcessesProxy(processes.ProcessesService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def getChildren(self, parent_context_id, attached_only, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service,
- "getChildren", (parent_context_id, attached_only))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
- def getContext(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = ProcessContext(service, args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def getEnvironment(self, done):
- done = self._makeCallback(done)
- service = self
- class GetEnvCommand(Command):
- def __init__(self):
- super(GetEnvCommand, self).__init__(service.channel, service, "getEnvironment", None)
- def done(self, error, args):
- env = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- env = _toEnvMap(args[1])
- done.doneGetEnvironment(self.token, error, env)
- return GetEnvCommand().token
-
- def start(self, directory, file, command_line, environment, attach, done):
- done = self._makeCallback(done)
- service = self
- env = _toEnvStringArray(environment)
- class StartCommand(Command):
- def __init__(self):
- super(StartCommand, self).__init__(service.channel, service,
- "start", (directory, file, command_line, env, attach))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = ProcessContext(service, args[1])
- done.doneStart(self.token, error, ctx)
- return StartCommand().token
-
- def getSignalList(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetSignalsCommand(Command):
- def __init__(self):
- super(GetSignalsCommand, self).__init__(service.channel, service,
- "getSignalList", (context_id,))
- def done(self, error, args):
- list = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- list = args[1]
- done.doneGetSignalList(self.token, error, list)
- return GetSignalsCommand().token
-
- def getSignalMask(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetSignalMaskCommand(Command):
- def __init__(self):
- super(GetSignalMaskCommand, self).__init__(service.channel, service,
- "getSignalMask", (context_id,))
- def done(self, error, args):
- dont_stop = 0
- dont_pass = 0
- pending = 0
- if not error:
- assert len(args) == 4
- error = self.toError(args[0])
- dont_stop, dont_pass, pending = args[1:4]
- done.doneGetSignalMask(self.token, error, dont_stop, dont_pass, pending)
- return GetSignalMaskCommand().token
-
- def setSignalMask(self, context_id, dont_stop, dont_pass, done):
- done = self._makeCallback(done)
- service = self
- class SetSignalMaskCommand(Command):
- def __init__(self):
- super(SetSignalMaskCommand, self).__init__(service.channel, service,
- "setSignalMask", (context_id, dont_stop, dont_pass))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCommand(self.token, error)
- return SetSignalMaskCommand().token
-
- def signal(self, context_id, signal, done):
- done = self._makeCallback(done)
- service = self
- class SignalCommand(Command):
- def __init__(self):
- super(SignalCommand, self).__init__(service.channel, service,
- "signal", (context_id, signal))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCommand(self.token, error)
- return SignalCommand().token
-
- def addListener(self, listener):
- l = ChannelEventListener(self, listener)
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.get(listener)
- if l:
- del self.listeners[listener]
- self.channel.removeEventListener(self, l)
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "exited":
- assert len(args) == 2
- self.listener.exited(args[0], args[1])
- else:
- raise IOError("Processes service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
-
-def _toEnvStringArray(map):
- arr = []
- if not map: return arr
- for name, value in map.items():
- arr.append("%s=%s" % (name, value))
- return arr
-
-def _toEnvMap(arr):
- map = {}
- if not arr: return map
- for str in arr:
- i = str.find('=')
- if i >= 0: map[str[:i]] = str[i + 1:]
- else: map[str] = ""
- return map
+# *******************************************************************************
+# * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import channel
+from tcf.services import processes
+from tcf.channel.Command import Command
+
+class ProcessContext(processes.ProcessContext):
+ def __init__(self, service, props):
+ super(ProcessContext, self).__init__(props)
+ self.service = service
+
+ def attach(self, done):
+ return self._command("attach", done)
+
+ def detach(self, done):
+ return self._command("detach", done)
+
+ def terminate(self, done):
+ return self._command("terminate", done)
+
+ def _command(self, command, done):
+ service = self.service
+ done = service._makeCallback(done)
+ id = self.getID()
+ class _Command(Command):
+ def __init__(self):
+ super(_Command, self).__init__(service.channel, service,
+ command, (id,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneCommand(self.token, error)
+ return _Command().token
+
+class ProcessesProxy(processes.ProcessesService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def getChildren(self, parent_context_id, attached_only, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service,
+ "getChildren", (parent_context_id, attached_only))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+ def getContext(self, context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = ProcessContext(service, args[1])
+ done.doneGetContext(self.token, error, ctx)
+ return GetContextCommand().token
+
+ def getEnvironment(self, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetEnvCommand(Command):
+ def __init__(self):
+ super(GetEnvCommand, self).__init__(service.channel, service, "getEnvironment", None)
+ def done(self, error, args):
+ env = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ env = _toEnvMap(args[1])
+ done.doneGetEnvironment(self.token, error, env)
+ return GetEnvCommand().token
+
+ def start(self, directory, file, command_line, environment, attach, done):
+ done = self._makeCallback(done)
+ service = self
+ env = _toEnvStringArray(environment)
+ class StartCommand(Command):
+ def __init__(self):
+ super(StartCommand, self).__init__(service.channel, service,
+ "start", (directory, file, command_line, env, attach))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = ProcessContext(service, args[1])
+ done.doneStart(self.token, error, ctx)
+ return StartCommand().token
+
+ def getSignalList(self, context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetSignalsCommand(Command):
+ def __init__(self):
+ super(GetSignalsCommand, self).__init__(service.channel, service,
+ "getSignalList", (context_id,))
+ def done(self, error, args):
+ list = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ list = args[1]
+ done.doneGetSignalList(self.token, error, list)
+ return GetSignalsCommand().token
+
+ def getSignalMask(self, context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetSignalMaskCommand(Command):
+ def __init__(self):
+ super(GetSignalMaskCommand, self).__init__(service.channel, service,
+ "getSignalMask", (context_id,))
+ def done(self, error, args):
+ dont_stop = 0
+ dont_pass = 0
+ pending = 0
+ if not error:
+ assert len(args) == 4
+ error = self.toError(args[0])
+ dont_stop, dont_pass, pending = args[1:4]
+ done.doneGetSignalMask(self.token, error, dont_stop, dont_pass, pending)
+ return GetSignalMaskCommand().token
+
+ def setSignalMask(self, context_id, dont_stop, dont_pass, done):
+ done = self._makeCallback(done)
+ service = self
+ class SetSignalMaskCommand(Command):
+ def __init__(self):
+ super(SetSignalMaskCommand, self).__init__(service.channel, service,
+ "setSignalMask", (context_id, dont_stop, dont_pass))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneCommand(self.token, error)
+ return SetSignalMaskCommand().token
+
+ def signal(self, context_id, signal, done):
+ done = self._makeCallback(done)
+ service = self
+ class SignalCommand(Command):
+ def __init__(self):
+ super(SignalCommand, self).__init__(service.channel, service,
+ "signal", (context_id, signal))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneCommand(self.token, error)
+ return SignalCommand().token
+
+ def addListener(self, listener):
+ l = ChannelEventListener(self, listener)
+ self.channel.addEventListener(self, l)
+ self.listeners[listener] = l
+
+ def removeListener(self, listener):
+ l = self.listeners.get(listener)
+ if l:
+ del self.listeners[listener]
+ self.channel.removeEventListener(self, l)
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "exited":
+ assert len(args) == 2
+ self.listener.exited(args[0], args[1])
+ else:
+ raise IOError("Processes service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
+
+def _toEnvStringArray(map):
+ arr = []
+ if not map: return arr
+ for name, value in map.items():
+ arr.append("%s=%s" % (name, value))
+ return arr
+
+def _toEnvMap(arr):
+ map = {}
+ if not arr: return map
+ for str in arr:
+ i = str.find('=')
+ if i >= 0: map[str[:i]] = str[i + 1:]
+ else: map[str] = ""
+ return map
diff --git a/python/src/tcf/services/remote/ProcessesV1Proxy.py b/python/src/tcf/services/remote/ProcessesV1Proxy.py
index 5ebf28a3e..c16d15624 100644
--- a/python/src/tcf/services/remote/ProcessesV1Proxy.py
+++ b/python/src/tcf/services/remote/ProcessesV1Proxy.py
@@ -1,32 +1,32 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from . import ProcessesProxy
-from tcf.services import processes_v1
-from tcf.channel.Command import Command
-
-class ProcessesV1Proxy(ProcessesProxy.ProcessesProxy, processes_v1.ProcessesV1Service):
- def start(self, directory, file, command_line, environment, params, done):
- done = self._makeCallback(done)
- service = self
- env = ProcessesProxy._toEnvStringArray(environment)
- class StartCommand(Command):
- def __init__(self):
- super(StartCommand, self).__init__(service.channel, service,
- "start", (directory, file, command_line, env, params))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = ProcessesProxy.ProcessContext(service, args[1])
- done.doneStart(self.token, error, ctx)
- return StartCommand().token
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from . import ProcessesProxy
+from tcf.services import processes_v1
+from tcf.channel.Command import Command
+
+class ProcessesV1Proxy(ProcessesProxy.ProcessesProxy, processes_v1.ProcessesV1Service):
+ def start(self, directory, file, command_line, environment, params, done):
+ done = self._makeCallback(done)
+ service = self
+ env = ProcessesProxy._toEnvStringArray(environment)
+ class StartCommand(Command):
+ def __init__(self):
+ super(StartCommand, self).__init__(service.channel, service,
+ "start", (directory, file, command_line, env, params))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = ProcessesProxy.ProcessContext(service, args[1])
+ done.doneStart(self.token, error, ctx)
+ return StartCommand().token
diff --git a/python/src/tcf/services/remote/RegistersProxy.py b/python/src/tcf/services/remote/RegistersProxy.py
index f33eea147..fdf3d9ae8 100644
--- a/python/src/tcf/services/remote/RegistersProxy.py
+++ b/python/src/tcf/services/remote/RegistersProxy.py
@@ -1,176 +1,176 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import channel
-from tcf.services import registers
-from tcf.channel import toByteArray
-from tcf.channel.Command import Command
-
-class Context(registers.RegistersContext):
- def __init__(self, service, props):
- super(Context, self).__init__(props)
- self.service = service
-
- def getNamedValues(self):
- return _toValuesArray(self._props.get(registers.PROP_VALUES))
-
- def get(self, done):
- service = self.service
- done = service._makeCallback(done)
- id = self.getID()
- class GetCommand(Command):
- def __init__(self):
- super(GetCommand, self).__init__(service.channel, service, "get", (id,))
- def done(self, error, args):
- val = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- val = toByteArray(args[1])
- done.doneGet(self.token, error, val)
- return GetCommand().token
-
- def set(self, value, done):
- service = self.service
- done = service._makeCallback(done)
- id = self.getID()
- binary = bytearray(value)
- class SetCommand(Command):
- def __init__(self):
- super(SetCommand, self).__init__(service.channel, service, "set", (id, binary))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneSet(self.token, error)
- return SetCommand().token
-
- def search(self, filter, done):
- service = self.service
- done = service._makeCallback(done)
- id = self.getID()
- class SearchCommand(Command):
- def __init__(self):
- super(SearchCommand, self).__init__(service.channel, service, "search", (id, filter))
- def done(self, error, args):
- paths = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- paths = args[1]
- done.doneSearch(self.token, error, paths)
- return SearchCommand().token
-
-class RegistersProxy(registers.RegistersService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def getChildren(self, parent_context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
- def getContext(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = Context(service, args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def getm(self, locs, done):
- done = self._makeCallback(done)
- service = self
- class GetMCommand(Command):
- def __init__(self):
- super(GetMCommand, self).__init__(service.channel, service, "getm", (locs,))
- def done(self, error, args):
- val = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- val = toByteArray(args[1])
- done.doneGet(self.token, error, val)
- return GetMCommand().token
-
- def setm(self, locs, value, done):
- done = self._makeCallback(done)
- service = self
- binary = bytearray(value)
- class SetMCommand(Command):
- def __init__(self):
- super(SetMCommand, self).__init__(service.channel, service, "setm", (locs, binary))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneSet(self.token, error)
- return SetMCommand().token
-
- def addListener(self, listener):
- l = ChannelEventListener(self, listener)
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.get(listener)
- if l:
- del self.listeners[listener]
- self.channel.removeEventListener(self, l)
-
-class NamedValueInfo(registers.NamedValue):
- def __init__(self, m):
- desc = m.get("Description")
- name = m.get("Name")
- value = toByteArray(m.get("Value"))
- super(NamedValueInfo, self).__init__(value, name, desc)
-
-def _toValuesArray(o):
- if o is None: return None
- arr = []
- for m in o:
- arr.append(NamedValueInfo(m))
- return arr
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "contextChanged":
- self.listener.contextChanged()
- elif name == "registerChanged":
- assert len(args) == 1
- self.listener.registerChanged(args[0])
- else:
- raise IOError("Registers service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import channel
+from tcf.services import registers
+from tcf.channel import toByteArray
+from tcf.channel.Command import Command
+
+class Context(registers.RegistersContext):
+ def __init__(self, service, props):
+ super(Context, self).__init__(props)
+ self.service = service
+
+ def getNamedValues(self):
+ return _toValuesArray(self._props.get(registers.PROP_VALUES))
+
+ def get(self, done):
+ service = self.service
+ done = service._makeCallback(done)
+ id = self.getID()
+ class GetCommand(Command):
+ def __init__(self):
+ super(GetCommand, self).__init__(service.channel, service, "get", (id,))
+ def done(self, error, args):
+ val = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ val = toByteArray(args[1])
+ done.doneGet(self.token, error, val)
+ return GetCommand().token
+
+ def set(self, value, done):
+ service = self.service
+ done = service._makeCallback(done)
+ id = self.getID()
+ binary = bytearray(value)
+ class SetCommand(Command):
+ def __init__(self):
+ super(SetCommand, self).__init__(service.channel, service, "set", (id, binary))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneSet(self.token, error)
+ return SetCommand().token
+
+ def search(self, filter, done):
+ service = self.service
+ done = service._makeCallback(done)
+ id = self.getID()
+ class SearchCommand(Command):
+ def __init__(self):
+ super(SearchCommand, self).__init__(service.channel, service, "search", (id, filter))
+ def done(self, error, args):
+ paths = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ paths = args[1]
+ done.doneSearch(self.token, error, paths)
+ return SearchCommand().token
+
+class RegistersProxy(registers.RegistersService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def getChildren(self, parent_context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+ def getContext(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = Context(service, args[1])
+ done.doneGetContext(self.token, error, ctx)
+ return GetContextCommand().token
+
+ def getm(self, locs, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetMCommand(Command):
+ def __init__(self):
+ super(GetMCommand, self).__init__(service.channel, service, "getm", (locs,))
+ def done(self, error, args):
+ val = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ val = toByteArray(args[1])
+ done.doneGet(self.token, error, val)
+ return GetMCommand().token
+
+ def setm(self, locs, value, done):
+ done = self._makeCallback(done)
+ service = self
+ binary = bytearray(value)
+ class SetMCommand(Command):
+ def __init__(self):
+ super(SetMCommand, self).__init__(service.channel, service, "setm", (locs, binary))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneSet(self.token, error)
+ return SetMCommand().token
+
+ def addListener(self, listener):
+ l = ChannelEventListener(self, listener)
+ self.channel.addEventListener(self, l)
+ self.listeners[listener] = l
+
+ def removeListener(self, listener):
+ l = self.listeners.get(listener)
+ if l:
+ del self.listeners[listener]
+ self.channel.removeEventListener(self, l)
+
+class NamedValueInfo(registers.NamedValue):
+ def __init__(self, m):
+ desc = m.get("Description")
+ name = m.get("Name")
+ value = toByteArray(m.get("Value"))
+ super(NamedValueInfo, self).__init__(value, name, desc)
+
+def _toValuesArray(o):
+ if o is None: return None
+ arr = []
+ for m in o:
+ arr.append(NamedValueInfo(m))
+ return arr
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "contextChanged":
+ self.listener.contextChanged()
+ elif name == "registerChanged":
+ assert len(args) == 1
+ self.listener.registerChanged(args[0])
+ else:
+ raise IOError("Registers service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
diff --git a/python/src/tcf/services/remote/RunControlProxy.py b/python/src/tcf/services/remote/RunControlProxy.py
index 8c2832cf4..60d20fea8 100644
--- a/python/src/tcf/services/remote/RunControlProxy.py
+++ b/python/src/tcf/services/remote/RunControlProxy.py
@@ -1,158 +1,158 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import channel
-from tcf.services import runcontrol
-from tcf.channel.Command import Command
-
-class RunContext(runcontrol.RunControlContext):
- def __init__(self, service, props):
- super(RunContext, self).__init__(props)
- self.service = service
-
- def getState(self, done):
- service = self.service
- done = service._makeCallback(done)
- id = self.getID()
- class GetStateCommand(Command):
- def __init__(self):
- super(GetStateCommand, self).__init__(service.channel, service, "getState", (id,))
- def done(self, error, args):
- susp = False
- pc = None
- reason = None
- map = None
- if not error:
- assert len(args) == 5
- error = self.toError(args[0])
- susp = args[1]
- if args[2]: pc = str(args[2])
- reason = args[3]
- map = args[4]
- done.doneGetState(self.token, error, susp, pc, reason, map)
- return GetStateCommand().token
-
-# def resume(self, mode, count, done):
-# return self._command("resume", [self.getID(), mode, count], done)
-
- def resume(self, mode, count, params, done):
- if not params:
- return self._command("resume", (self.getID(), mode, count), done)
- else:
- return self._command("resume", (self.getID(), mode, count, params), done)
-
- def suspend(self, done):
- return self._command("suspend", (self.getID(),), done)
-
- def terminate(self, done):
- return self._command("terminate", (self.getID(),), done)
-
- def _command(self, cmd, args, done):
- service = self.service
- done = service._makeCallback(done)
- class RCCommand(Command):
- def __init__(self, cmd, args):
- super(RCCommand, self).__init__(service.channel, service, cmd, args)
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCommand(self.token, error)
- return RCCommand(cmd, args).token
-
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "contextSuspended":
- assert len(args) == 4
- self.listener.contextSuspended(args[0], args[1], args[2], args[3])
- elif name == "contextResumed":
- assert len(args) == 1
- self.listener.contextResumed(args[0])
- elif name == "contextAdded":
- assert len(args) == 1
- self.listener.contextAdded(_toContextArray(self.service,args[0]))
- elif name == "contextChanged":
- assert len(args) == 1
- self.listener.contextChanged(_toContextArray(self.service,args[0]))
- elif name == "contextRemoved":
- assert len(args) == 1
- self.listener.contextRemoved(args[0])
- elif name == "contextException":
- assert len(args) == 2
- self.listener.contextException(args[0], args[1])
- elif name == "containerSuspended":
- assert len(args) == 5
- self.listener.containerSuspended(args[0], args[1], args[2], args[3], args[4])
- elif name == "containerResumed":
- assert len(args) == 1
- self.listener.containerResumed(args[0])
- else:
- raise IOError("RunControl service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
-
-class RunControlProxy(runcontrol.RunControlService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def addListener(self, listener):
- l = ChannelEventListener(self, listener)
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.get(listener)
- if l:
- del self.listeners[listener]
- self.channel.removeEventListener(self, l)
-
- def getContext(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = RunContext(service, args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def getChildren(self, parent_context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
-def _toContextArray(svc,o):
- if o is None: return None
- ctx = []
- for m in o: ctx.append(RunContext(svc,m))
- return ctx
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import channel
+from tcf.services import runcontrol
+from tcf.channel.Command import Command
+
+class RunContext(runcontrol.RunControlContext):
+ def __init__(self, service, props):
+ super(RunContext, self).__init__(props)
+ self.service = service
+
+ def getState(self, done):
+ service = self.service
+ done = service._makeCallback(done)
+ id = self.getID()
+ class GetStateCommand(Command):
+ def __init__(self):
+ super(GetStateCommand, self).__init__(service.channel, service, "getState", (id,))
+ def done(self, error, args):
+ susp = False
+ pc = None
+ reason = None
+ map = None
+ if not error:
+ assert len(args) == 5
+ error = self.toError(args[0])
+ susp = args[1]
+ if args[2]: pc = str(args[2])
+ reason = args[3]
+ map = args[4]
+ done.doneGetState(self.token, error, susp, pc, reason, map)
+ return GetStateCommand().token
+
+# def resume(self, mode, count, done):
+# return self._command("resume", [self.getID(), mode, count], done)
+
+ def resume(self, mode, count, params, done):
+ if not params:
+ return self._command("resume", (self.getID(), mode, count), done)
+ else:
+ return self._command("resume", (self.getID(), mode, count, params), done)
+
+ def suspend(self, done):
+ return self._command("suspend", (self.getID(),), done)
+
+ def terminate(self, done):
+ return self._command("terminate", (self.getID(),), done)
+
+ def _command(self, cmd, args, done):
+ service = self.service
+ done = service._makeCallback(done)
+ class RCCommand(Command):
+ def __init__(self, cmd, args):
+ super(RCCommand, self).__init__(service.channel, service, cmd, args)
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneCommand(self.token, error)
+ return RCCommand(cmd, args).token
+
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "contextSuspended":
+ assert len(args) == 4
+ self.listener.contextSuspended(args[0], args[1], args[2], args[3])
+ elif name == "contextResumed":
+ assert len(args) == 1
+ self.listener.contextResumed(args[0])
+ elif name == "contextAdded":
+ assert len(args) == 1
+ self.listener.contextAdded(_toContextArray(self.service,args[0]))
+ elif name == "contextChanged":
+ assert len(args) == 1
+ self.listener.contextChanged(_toContextArray(self.service,args[0]))
+ elif name == "contextRemoved":
+ assert len(args) == 1
+ self.listener.contextRemoved(args[0])
+ elif name == "contextException":
+ assert len(args) == 2
+ self.listener.contextException(args[0], args[1])
+ elif name == "containerSuspended":
+ assert len(args) == 5
+ self.listener.containerSuspended(args[0], args[1], args[2], args[3], args[4])
+ elif name == "containerResumed":
+ assert len(args) == 1
+ self.listener.containerResumed(args[0])
+ else:
+ raise IOError("RunControl service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
+
+class RunControlProxy(runcontrol.RunControlService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def addListener(self, listener):
+ l = ChannelEventListener(self, listener)
+ self.channel.addEventListener(self, l)
+ self.listeners[listener] = l
+
+ def removeListener(self, listener):
+ l = self.listeners.get(listener)
+ if l:
+ del self.listeners[listener]
+ self.channel.removeEventListener(self, l)
+
+ def getContext(self, context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (context_id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = RunContext(service, args[1])
+ done.doneGetContext(self.token, error, ctx)
+ return GetContextCommand().token
+
+ def getChildren(self, parent_context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+def _toContextArray(svc,o):
+ if o is None: return None
+ ctx = []
+ for m in o: ctx.append(RunContext(svc,m))
+ return ctx
diff --git a/python/src/tcf/services/remote/StackTraceProxy.py b/python/src/tcf/services/remote/StackTraceProxy.py
index b551af36f..5a2d6288f 100644
--- a/python/src/tcf/services/remote/StackTraceProxy.py
+++ b/python/src/tcf/services/remote/StackTraceProxy.py
@@ -1,54 +1,54 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf.services import stacktrace
-from tcf.channel.Command import Command
-
-class StackTraceProxy(stacktrace.StackTraceService):
- def __init__(self, channel):
- self.channel = channel
-
- def getChildren(self, parent_context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
- def getContext(self, ids, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (ids,))
- def done(self, error, args):
- ctxs = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[1])
- ctxs = service.toContextArray(args[0])
- done.doneGetContext(self.token, error, ctxs)
- return GetContextCommand().token
-
- def toContextArray(self, ctxProps):
- if ctxProps is None: return None
- ctxs = []
- for props in ctxProps:
- ctxs.append(stacktrace.StackTraceContext(props))
- return ctxs
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf.services import stacktrace
+from tcf.channel.Command import Command
+
+class StackTraceProxy(stacktrace.StackTraceService):
+ def __init__(self, channel):
+ self.channel = channel
+
+ def getChildren(self, parent_context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+ def getContext(self, ids, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (ids,))
+ def done(self, error, args):
+ ctxs = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[1])
+ ctxs = service.toContextArray(args[0])
+ done.doneGetContext(self.token, error, ctxs)
+ return GetContextCommand().token
+
+ def toContextArray(self, ctxProps):
+ if ctxProps is None: return None
+ ctxs = []
+ for props in ctxProps:
+ ctxs.append(stacktrace.StackTraceContext(props))
+ return ctxs
diff --git a/python/src/tcf/services/remote/StreamsProxy.py b/python/src/tcf/services/remote/StreamsProxy.py
index d4149099d..67297e7d1 100644
--- a/python/src/tcf/services/remote/StreamsProxy.py
+++ b/python/src/tcf/services/remote/StreamsProxy.py
@@ -1,146 +1,146 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf.services import streams
-from tcf import channel
-from tcf.channel.Command import Command
-
-class StreamsProxy(streams.StreamsService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def connect(self, stream_id, done):
- done = self._makeCallback(done)
- service = self
- class ConnectCommand(Command):
- def __init__(self):
- super(ConnectCommand, self).__init__(service.channel, service, "connect", (stream_id,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneConnect(self.token, error)
- return ConnectCommand().token
-
- def disconnect(self, stream_id, done):
- done = self._makeCallback(done)
- service = self
- class DisconnectCommand(Command):
- def __init__(self):
- super(DisconnectCommand, self).__init__(service.channel, service, "disconnect", (stream_id,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneDisconnect(self.token, error)
- return DisconnectCommand().token
-
- def eos(self, stream_id, done):
- done = self._makeCallback(done)
- service = self
- class EOSCommand(Command):
- def __init__(self):
- super(EOSCommand, self).__init__(service.channel, service, "eos", (stream_id,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneEOS(self.token, error)
- return EOSCommand().token
-
- def read(self, stream_id, size, done):
- done = self._makeCallback(done)
- service = self
- class ReadCommand(Command):
- def __init__(self):
- super(ReadCommand, self).__init__(service.channel, service, "read", (stream_id, size))
- def done(self, error, args):
- lost_size = 0
- data = None
- eos = False
- if not error:
- assert len(args) == 4
- data = channel.toByteArray(args[0])
- error = self.toError(args[1])
- lost_size = args[2]
- eos = args[3]
- done.doneRead(self.token, error, lost_size, data, eos)
- return ReadCommand().token
-
- def subscribe(self, stream_type, listener, done):
- done = self._makeCallback(done)
- service = self
- class SubscribeCommand(Command):
- def __init__(self):
- super(SubscribeCommand, self).__init__(service.channel, service, "subscribe", (stream_type,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- if not error:
- l = ChannelEventListener(service, listener)
- service.listeners[listener] = l
- service.channel.addEventListener(service, l)
- done.doneSubscribe(self.token, error)
- return SubscribeCommand().token
-
- def unsubscribe(self, stream_type, listener, done):
- done = self._makeCallback(done)
- service = self
- class UnsubscribeCommand(Command):
- def __init__(self):
- super(UnsubscribeCommand, self).__init__(service.channel, service, "unsubscribe", (stream_type,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- if not error:
- l = service.listeners.pop(listener, None)
- if l: service.channel.removeEventListener(service, l)
- done.doneUnsubscribe(self.token, error)
- return UnsubscribeCommand().token
-
- def write(self, stream_id, buf, offset, size, done):
- done = self._makeCallback(done)
- service = self
- binary = buf[offset:offset+size]
- class WriteCommand(Command):
- def __init__(self):
- super(WriteCommand, self).__init__(service.channel, service, "write", (stream_id, binary))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneWrite(self.token, error)
- return WriteCommand().token
-
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "created":
- if len(args) == 3:
- self.listener.created(args[0], args[1], args[2])
- else:
- assert len(args) == 2
- self.listener.created(args[0], args[1], None)
- elif name == "disposed":
- assert len(args) == 2
- self.listener.disposed(args[0], args[1])
- else:
- raise IOError("Streams service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf.services import streams
+from tcf import channel
+from tcf.channel.Command import Command
+
+class StreamsProxy(streams.StreamsService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def connect(self, stream_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class ConnectCommand(Command):
+ def __init__(self):
+ super(ConnectCommand, self).__init__(service.channel, service, "connect", (stream_id,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneConnect(self.token, error)
+ return ConnectCommand().token
+
+ def disconnect(self, stream_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class DisconnectCommand(Command):
+ def __init__(self):
+ super(DisconnectCommand, self).__init__(service.channel, service, "disconnect", (stream_id,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneDisconnect(self.token, error)
+ return DisconnectCommand().token
+
+ def eos(self, stream_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class EOSCommand(Command):
+ def __init__(self):
+ super(EOSCommand, self).__init__(service.channel, service, "eos", (stream_id,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneEOS(self.token, error)
+ return EOSCommand().token
+
+ def read(self, stream_id, size, done):
+ done = self._makeCallback(done)
+ service = self
+ class ReadCommand(Command):
+ def __init__(self):
+ super(ReadCommand, self).__init__(service.channel, service, "read", (stream_id, size))
+ def done(self, error, args):
+ lost_size = 0
+ data = None
+ eos = False
+ if not error:
+ assert len(args) == 4
+ data = channel.toByteArray(args[0])
+ error = self.toError(args[1])
+ lost_size = args[2]
+ eos = args[3]
+ done.doneRead(self.token, error, lost_size, data, eos)
+ return ReadCommand().token
+
+ def subscribe(self, stream_type, listener, done):
+ done = self._makeCallback(done)
+ service = self
+ class SubscribeCommand(Command):
+ def __init__(self):
+ super(SubscribeCommand, self).__init__(service.channel, service, "subscribe", (stream_type,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ if not error:
+ l = ChannelEventListener(service, listener)
+ service.listeners[listener] = l
+ service.channel.addEventListener(service, l)
+ done.doneSubscribe(self.token, error)
+ return SubscribeCommand().token
+
+ def unsubscribe(self, stream_type, listener, done):
+ done = self._makeCallback(done)
+ service = self
+ class UnsubscribeCommand(Command):
+ def __init__(self):
+ super(UnsubscribeCommand, self).__init__(service.channel, service, "unsubscribe", (stream_type,))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ if not error:
+ l = service.listeners.pop(listener, None)
+ if l: service.channel.removeEventListener(service, l)
+ done.doneUnsubscribe(self.token, error)
+ return UnsubscribeCommand().token
+
+ def write(self, stream_id, buf, offset, size, done):
+ done = self._makeCallback(done)
+ service = self
+ binary = buf[offset:offset+size]
+ class WriteCommand(Command):
+ def __init__(self):
+ super(WriteCommand, self).__init__(service.channel, service, "write", (stream_id, binary))
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneWrite(self.token, error)
+ return WriteCommand().token
+
+
+class ChannelEventListener(channel.EventListener):
+ def __init__(self, service, listener):
+ self.service = service
+ self.listener = listener
+ def event(self, name, data):
+ try:
+ args = channel.fromJSONSequence(data)
+ if name == "created":
+ if len(args) == 3:
+ self.listener.created(args[0], args[1], args[2])
+ else:
+ assert len(args) == 2
+ self.listener.created(args[0], args[1], None)
+ elif name == "disposed":
+ assert len(args) == 2
+ self.listener.disposed(args[0], args[1])
+ else:
+ raise IOError("Streams service: unknown event: " + name);
+ except Exception as x:
+ self.service.channel.terminate(x)
diff --git a/python/src/tcf/services/remote/SymbolsProxy.py b/python/src/tcf/services/remote/SymbolsProxy.py
index 7d911f6c9..72c3b10fb 100644
--- a/python/src/tcf/services/remote/SymbolsProxy.py
+++ b/python/src/tcf/services/remote/SymbolsProxy.py
@@ -1,121 +1,121 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf import channel
-from tcf.services import symbols
-from tcf.channel.Command import Command
-
-
-class Context(symbols.Symbol):
- def __init__(self, props):
- super(Context, self).__init__(props)
- self.value = channel.toByteArray(props.get(symbols.PROP_VALUE))
-
- def getValue(self):
- return self.value
-
-
-class SymbolsProxy(symbols.SymbolsService):
- def __init__(self, channel):
- self.channel = channel
-
- def getContext(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = Context(args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def getChildren(self, parent_context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
- def find(self, context_id, ip, name, done):
- done = self._makeCallback(done)
- service = self
- class FindCommand(Command):
- def __init__(self):
- super(FindCommand, self).__init__(service.channel, service, "find", (context_id, ip, name))
- def done(self, error, args):
- id = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- id = args[1]
- done.doneFind(self.token, error, id)
- return FindCommand().token
-
- def findByAddr(self, context_id, addr, done):
- done = self._makeCallback(done)
- service = self
- class FindByAddrCommand(Command):
- def __init__(self):
- super(FindByAddrCommand, self).__init__(service.channel, service, "findByAddr", (context_id, addr))
- def done(self, error, args):
- id = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- id = args[1]
- done.doneFind(self.token, error, id)
- return FindByAddrCommand().token
-
- def list(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class ListCommand(Command):
- def __init__(self):
- super(ListCommand, self).__init__(service.channel, service, "list", (context_id,))
- def done(self, error, args):
- lst = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- lst = args[1]
- done.doneList(self.token, error, lst)
- return ListCommand().token
-
- def findFrameInfo(self, context_id, address, done):
- done = self._makeCallback(done)
- service = self
- class FindFrameInfoCommand(Command):
- def __init__(self):
- super(FindFrameInfoCommand, self).__init__(service.channel, service, "findFrameInfo", (context_id, address))
- def done(self, error, args):
- address = None
- size = None
- fp_cmds = None
- reg_cmds = None
- if not error:
- assert len(args) == 5
- error = self.toError(args[0])
- address, size, fp_cmds, reg_cmds = args[1:5]
- done.doneFindFrameInfo(self.token, error, address, size, fp_cmds, reg_cmds)
- return FindFrameInfoCommand().token
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf import channel
+from tcf.services import symbols
+from tcf.channel.Command import Command
+
+
+class Context(symbols.Symbol):
+ def __init__(self, props):
+ super(Context, self).__init__(props)
+ self.value = channel.toByteArray(props.get(symbols.PROP_VALUE))
+
+ def getValue(self):
+ return self.value
+
+
+class SymbolsProxy(symbols.SymbolsService):
+ def __init__(self, channel):
+ self.channel = channel
+
+ def getContext(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = Context(args[1])
+ done.doneGetContext(self.token, error, ctx)
+ return GetContextCommand().token
+
+ def getChildren(self, parent_context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+ def find(self, context_id, ip, name, done):
+ done = self._makeCallback(done)
+ service = self
+ class FindCommand(Command):
+ def __init__(self):
+ super(FindCommand, self).__init__(service.channel, service, "find", (context_id, ip, name))
+ def done(self, error, args):
+ id = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ id = args[1]
+ done.doneFind(self.token, error, id)
+ return FindCommand().token
+
+ def findByAddr(self, context_id, addr, done):
+ done = self._makeCallback(done)
+ service = self
+ class FindByAddrCommand(Command):
+ def __init__(self):
+ super(FindByAddrCommand, self).__init__(service.channel, service, "findByAddr", (context_id, addr))
+ def done(self, error, args):
+ id = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ id = args[1]
+ done.doneFind(self.token, error, id)
+ return FindByAddrCommand().token
+
+ def list(self, context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class ListCommand(Command):
+ def __init__(self):
+ super(ListCommand, self).__init__(service.channel, service, "list", (context_id,))
+ def done(self, error, args):
+ lst = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ lst = args[1]
+ done.doneList(self.token, error, lst)
+ return ListCommand().token
+
+ def findFrameInfo(self, context_id, address, done):
+ done = self._makeCallback(done)
+ service = self
+ class FindFrameInfoCommand(Command):
+ def __init__(self):
+ super(FindFrameInfoCommand, self).__init__(service.channel, service, "findFrameInfo", (context_id, address))
+ def done(self, error, args):
+ address = None
+ size = None
+ fp_cmds = None
+ reg_cmds = None
+ if not error:
+ assert len(args) == 5
+ error = self.toError(args[0])
+ address, size, fp_cmds, reg_cmds = args[1:5]
+ done.doneFindFrameInfo(self.token, error, address, size, fp_cmds, reg_cmds)
+ return FindFrameInfoCommand().token
diff --git a/python/src/tcf/services/remote/SysMonitorProxy.py b/python/src/tcf/services/remote/SysMonitorProxy.py
index 04aad1969..bf1f16bd7 100644
--- a/python/src/tcf/services/remote/SysMonitorProxy.py
+++ b/python/src/tcf/services/remote/SysMonitorProxy.py
@@ -1,77 +1,77 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. self program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies self distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf.services import sysmonitor
-from tcf.channel.Command import Command
-
-class SysMonitorProxy(sysmonitor.SysMonitorService):
- def __init__(self, channel):
- self.channel = channel
-
- def getChildren(self, parent_context_id, done):
- done = self._makeCallback(done)
- service = self
- class GetChildrenCommand(Command):
- def __init__(self):
- super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
- def done(self, error, args):
- contexts = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- contexts = args[1]
- done.doneGetChildren(self.token, error, contexts)
- return GetChildrenCommand().token
-
- def getContext(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = sysmonitor.SysMonitorContext(args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def getCommandLine(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetCommandLineCommand(Command):
- def __init__(self):
- super(GetCommandLineCommand, self).__init__(service.channel, service, "getCommandLine", (id,))
- def done(self, error, args):
- arr = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- arr = args[1]
- done.doneGetCommandLine(self.token, error, arr)
- return GetCommandLineCommand().token
-
- def getEnvironment(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetEnvironmentCommand(Command):
- def __init__(self):
- super(GetEnvironmentCommand, self).__init__(service.channel, service, "getEnvironment", (id,))
- def done(self, error, args):
- arr = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- arr = args[1]
- done.doneGetCommandLine(self.token, error, arr)
- return GetEnvironmentCommand().token
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. self program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies self distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf.services import sysmonitor
+from tcf.channel.Command import Command
+
+class SysMonitorProxy(sysmonitor.SysMonitorService):
+ def __init__(self, channel):
+ self.channel = channel
+
+ def getChildren(self, parent_context_id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetChildrenCommand(Command):
+ def __init__(self):
+ super(GetChildrenCommand, self).__init__(service.channel, service, "getChildren", (parent_context_id,))
+ def done(self, error, args):
+ contexts = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ contexts = args[1]
+ done.doneGetChildren(self.token, error, contexts)
+ return GetChildrenCommand().token
+
+ def getContext(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ if args[1]: ctx = sysmonitor.SysMonitorContext(args[1])
+ done.doneGetContext(self.token, error, ctx)
+ return GetContextCommand().token
+
+ def getCommandLine(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetCommandLineCommand(Command):
+ def __init__(self):
+ super(GetCommandLineCommand, self).__init__(service.channel, service, "getCommandLine", (id,))
+ def done(self, error, args):
+ arr = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ arr = args[1]
+ done.doneGetCommandLine(self.token, error, arr)
+ return GetCommandLineCommand().token
+
+ def getEnvironment(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetEnvironmentCommand(Command):
+ def __init__(self):
+ super(GetEnvironmentCommand, self).__init__(service.channel, service, "getEnvironment", (id,))
+ def done(self, error, args):
+ arr = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+ arr = args[1]
+ done.doneGetCommandLine(self.token, error, arr)
+ return GetEnvironmentCommand().token
diff --git a/python/src/tcf/services/remote/TerminalsProxy.py b/python/src/tcf/services/remote/TerminalsProxy.py
index 5e68c3406..22217e27b 100644
--- a/python/src/tcf/services/remote/TerminalsProxy.py
+++ b/python/src/tcf/services/remote/TerminalsProxy.py
@@ -1,123 +1,123 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-from tcf.services import terminals
-from tcf import channel
-from tcf.channel.Command import Command
-
-class TerminalContext(terminals.TerminalContext):
- def __init__(self, service, props):
- super(TerminalContext, self).__init__(props)
- self.service = service
-
- def exit(self, done):
- service = self.service
- done = service._makeCallback(done)
- id = self.getID()
- class ExitCommand(Command):
- def __init__(self, cmd, args):
- super(ExitCommand, self).__init__(service.channel, service, "exit", id)
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCommand(self.token, error)
- return ExitCommand().token
-
-
-class TerminalsProxy(terminals.TerminalsService):
- def __init__(self, channel):
- self.channel = channel
- self.listeners = {}
-
- def getContext(self, id, done):
- done = self._makeCallback(done)
- service = self
- class GetContextCommand(Command):
- def __init__(self):
- super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = TerminalContext(service, args[1])
- done.doneGetContext(self.token, error, ctx)
- return GetContextCommand().token
-
- def launch(self, type, encoding, environment, done):
- done = self._makeCallback(done)
- service = self
- class LaunchCommand(Command):
- def __init__(self):
- super(LaunchCommand, self).__init__(service.channel, service, "launch", (type, encoding, environment))
- def done(self, error, args):
- ctx = None
- if not error:
- assert len(args) == 2
- error = self.toError(args[0])
- if args[1]: ctx = TerminalContext(service, args[1])
- done.doneLaunch(self.token, error, ctx)
- return LaunchCommand().token
-
- def setWinSize(self, context_id, newWidth, newHeight, done):
- done = self._makeCallback(done)
- service = self
- class SetWinSizeCommand(Command):
- def __init__(self):
- super(SetWinSizeCommand, self).__init__(service.channel, service, "setWinSize", (context_id, newWidth, newHeight))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCommand(self.token, error)
- return SetWinSizeCommand().token
-
- def exit(self, context_id, done):
- done = self._makeCallback(done)
- service = self
- class ExitCommand(Command):
- def __init__(self):
- super(ExitCommand, self).__init__(service.channel, service, "exit", (context_id,))
- def done(self, error, args):
- if not error:
- assert len(args) == 1
- error = self.toError(args[0])
- done.doneCommand(self.token, error)
- return ExitCommand().token
-
- def addListener(self, listener):
- l = ChannelEventListener()
- self.channel.addEventListener(self, l)
- self.listeners[listener] = l
-
- def removeListener(self, listener):
- l = self.listeners.pop(listener, None)
- if l: self.channel.removeEventListener(self, l)
-
-
-class ChannelEventListener(channel.EventListener):
- def __init__(self, service, listener):
- self.service = service
- self.listener = listener
- def event(self, name, data):
- try:
- args = channel.fromJSONSequence(data)
- if name == "exited":
- assert len(args) == 2
- self.listener.exited(args[0], args[1])
- elif name == "winSizeChanged":
- assert len(args) == 3
- self.listener.winSizeChanged(args[0], args[1], args[2])
- else:
- raise IOError("Terminals service: unknown event: " + name);
- except Exception as x:
- self.service.channel.terminate(x)
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+from tcf.services import terminals
+from tcf import channel
+from tcf.channel.Command import Command
+
+class TerminalContext(terminals.TerminalContext):
+ def __init__(self, service, props):
+ super(TerminalContext, self).__init__(props)
+ self.service = service
+
+ def exit(self, done):
+ service = self.service
+ done = service._makeCallback(done)
+ id = self.getID()
+ class ExitCommand(Command):
+ def __init__(self, cmd, args):
+ super(ExitCommand, self).__init__(service.channel, service, "exit", id)
+ def done(self, error, args):
+ if not error:
+ assert len(args) == 1
+ error = self.toError(args[0])
+ done.doneCommand(self.token, error)
+ return ExitCommand().token
+
+
+class TerminalsProxy(terminals.TerminalsService):
+ def __init__(self, channel):
+ self.channel = channel
+ self.listeners = {}
+
+ def getContext(self, id, done):
+ done = self._makeCallback(done)
+ service = self
+ class GetContextCommand(Command):
+ def __init__(self):
+ super(GetContextCommand, self).__init__(service.channel, service, "getContext", (id,))
+ def done(self, error, args):
+ ctx = None
+ if not error:
+ assert len(args) == 2
+ error = self.toError(args[0])
+