Skip to content

Commit

Permalink
Init support for SimpleIoT Mesh
Browse files Browse the repository at this point in the history
  • Loading branch information
ivankravets committed Dec 25, 2015
1 parent 262a38c commit 1f575f3
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 48 deletions.
4 changes: 2 additions & 2 deletions smartanthill/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

# pylint: disable=W1401

VERSION = (0, 0, "0.dev4")
FIRMWARE_VERSION = (0, 0, 2)
VERSION = (0, 0, "0.dev5")
FIRMWARE_VERSION = (0, 0, 3)

__version__ = ".".join([str(s) for s in VERSION])

Expand Down
2 changes: 1 addition & 1 deletion smartanthill/cc/embedded
31 changes: 14 additions & 17 deletions smartanthill/network/commstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
class CommStackServerService(SAMultiService):

def __init__(self, name, options):
assert set(["device_id", "port", "eeprom_path"]) <= set(options.keys())
assert set(["port", "eeprom_path"]) <= set(options.keys())
SAMultiService.__init__(self, name, options)
self._litemq = get_service_named("litemq")
self._process = None
Expand Down Expand Up @@ -85,20 +85,16 @@ def get_server_bin():
def on_server_started(self, port):
self.log.info("Server has been started on port %d" % port)
self._litemq.produce(
"network", "commstack.server.started",
{"device_id": self.options['device_id'], "port": port}
)
"network", "commstack.server.started", {"port": port})


class CommStackClientFactory(protocol.ClientFactory):

def __init__(self, name, device_id):
def __init__(self, name):
self.name = name
self.log = Logger(self.name)
self.device_id = device_id
self._litemq = get_service_named("litemq")
self._protocol = None
self._source_id = 0

def buildProtocol(self, addr):
self._protocol = CommStackClientProtocol()
Expand Down Expand Up @@ -126,25 +122,25 @@ def from_client_callback(self, message, properties):
self.log.debug("Incoming from Client: %s and properties=%s" %
(message, properties))
assert isinstance(message, ControlMessage)
self._source_id = message.source
data = message.data
assert isinstance(data, bytearray)
# data.insert(0, self.device_id) # destination id
data.insert(0, 0x01) # first packet in chain
data.insert(1, 0x02) # SACCP_NEW_PROGRAM
assert isinstance(message.data, bytearray)
data = bytearray()
data.append(0x01) # first packet in chain
data.append(0x02) # SACCP_NEW_PROGRAM
data.extend(message.data)
self._protocol.send_data(
CommStackClientProtocol.PACKET_DIRECTION_CLIENT_TO_COMMSTACK,
message.destination,
data
)

def to_client_callback(self, message):
cm = ControlMessage(self.device_id, self._source_id,
def to_client_callback(self, source_id, message):
cm = ControlMessage(source_id, 0,
bytearray(message[1:])) # strip 1-st chain's byte
self.log.debug("Outgoing to Client: %s" % cm)
self._litemq.produce("network", "commstack->client", cm)

def to_client_errback(self, reason):
cm = ControlMessage(self.device_id, self._source_id)
def to_client_errback(self, source_id, reason):
cm = ControlMessage(source_id, 0)
self.log.error("Outgoing to Client: %s, error: %s" % (cm, reason))
self._litemq.produce("network", "commstack->error", (cm, reason))

Expand All @@ -153,6 +149,7 @@ def from_hub_callback(self, message, properties):
(hexlify(message), properties))
self._protocol.send_data(
CommStackClientProtocol.PACKET_DIRECTION_HUB_TO_COMMSTACK,
0, # bus_id, @TODO (0x0, 0x0)
message
)

Expand Down
25 changes: 14 additions & 11 deletions smartanthill/network/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from binascii import hexlify
from struct import pack
from struct import pack, unpack

from twisted.internet import protocol
from twisted.protocols.basic import LineReceiver
Expand All @@ -31,7 +31,7 @@ def __init__(self, source, destination, data=None):
self.data = data or bytearray()
assert isinstance(data, bytearray)

assert 0 <= self.source <= 255 and 0 <= self.destination <= 255
assert 0 <= self.source <= 65535 and 0 <= self.destination <= 65535
assert self.source != self.destination

def __repr__(self):
Expand Down Expand Up @@ -67,7 +67,8 @@ def outReceived(self, data):

def outLineReceived(self, line):
line = line.strip()
self.factory.log.debug(line)
if "siot_mesh_at_root_get_next_update" not in line:
self.factory.log.debug(line)
if not self._port_is_found:
self._parse_server_port(line)

Expand Down Expand Up @@ -98,23 +99,25 @@ class CommStackClientProtocol(protocol.Protocol):
PACKET_DIRECTION_COMMSTACK_TO_HUB = 35
PACKET_DIRECTION_COMMSTACK_INTERNAL_ERROR = 47

def send_data(self, direction, data):
assert isinstance(data, bytearray)
packet = pack("HB", len(data), direction)
packet += str(data)
self.transport.write(packet)
def send_data(self, direction, address, payload):
assert isinstance(payload, bytearray)
packet = bytearray(pack("HHB", len(payload), address, direction))
packet.extend(payload)
self.transport.write(str(packet))
self.factory.log.debug("Sent packet %s" % hexlify(packet))

def dataReceived(self, data):
data = bytearray(data)
self.factory.log.debug("Received data %s" % hexlify(data))
direction = data[2]
direction = data[4]
if direction == self.PACKET_DIRECTION_COMMSTACK_TO_HUB:
return self.factory.to_hub_callback(data[3:])
return self.factory.to_hub_callback(data[5:])
elif direction == self.PACKET_DIRECTION_COMMSTACK_TO_CLIENT:
return self.factory.to_client_callback(data[3:])
return self.factory.to_client_callback(
unpack("H", data[2:4]), data[5:])
elif direction == self.PACKET_DIRECTION_COMMSTACK_INTERNAL_ERROR:
return self.factory.to_client_errback(
unpack("H", data[2:4]),
NetworkCommStackServerInternalError())
raise SABaseException("Invalid direction %d" % direction)

Expand Down
28 changes: 13 additions & 15 deletions smartanthill/network/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from twisted.application.internet import TCPClient # pylint: disable=E0611

from smartanthill.configprocessor import ConfigProcessor
from smartanthill.network.commstack import (CommStackClientFactory,
CommStackServerService)
from smartanthill.network.hub import HubService
Expand All @@ -43,17 +44,15 @@ def startService(self):
callback=self.on_commstack_server_started
)

# initialize Communication Stack per device
for device in get_service_named("device").get_devices().values():
device_id = device.get_id()
CommStackServerService(
"network.commstack.server.%d" % device_id,
dict(
device_id=device_id,
port=0, # allow system to assign free port
eeprom_path=join(device.get_conf_dir(), "eeprom.dat")
)
).setServiceParent(self)
# initialize Communication Stack
CommStackServerService(
"network.commstack.server",
dict(
port=0, # allow system to assign free port
eeprom_path=join(
ConfigProcessor().get("workspace"), "commstack.dat")
)
).setServiceParent(self)

# initialize hubs
for i, t in enumerate(self.options.get("hubs", [])):
Expand All @@ -74,15 +73,14 @@ def _on_stop(_):
return d

def on_commstack_server_started(self, message, properties):
assert set(["device_id", "port"]) == set(message.keys())
assert set(["port"]) == set(message.keys())
self.start_commstack_client(**message)

def start_commstack_client(self, device_id, port):
def start_commstack_client(self, port):
TCPClient(
"127.0.0.1", port,
CommStackClientFactory(
"network.commstack.client.%d" % device_id,
device_id
"network.commstack.client"
)
).setServiceParent(self)

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# DAMAGE

[tox]
envlist = py26, py27, docs, lint, coverage
envlist = py27, docs, lint, coverage

[testenv:develop]
basepython = python2.7
Expand Down

0 comments on commit 1f575f3

Please sign in to comment.