Added OMCI message parsing tests
Change-Id: Ic864446241c3507dcfb389c7e774d0aa79de3b55
diff --git a/common/frameio/frameio.py b/common/frameio/frameio.py
index 0a222ad..4611c14 100644
--- a/common/frameio/frameio.py
+++ b/common/frameio/frameio.py
@@ -53,7 +53,7 @@
"""
Return a hexadecimal string encoding of input buffer
"""
- return ' '.join('%02x' % ord(c) for c in buffer)
+ return ''.join('%02x' % ord(c) for c in buffer)
class _SelectWakerDescriptor(object):
diff --git a/maple_experiments/chat.py b/maple_experiments/chat.py
new file mode 100755
index 0000000..358b728
--- /dev/null
+++ b/maple_experiments/chat.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+import sys
+from time import sleep
+
+from scapy.packet import Packet
+from twisted.spread import pb
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, returnValue, DeferredQueue
+from twisted.python import util
+
+from common.frameio.frameio import hexify
+from common.utils.asleep import asleep
+from voltha.extensions.omci.omci import *
+
+
+class OmciProxy(pb.Root):
+
+ def __init__(self):
+ reactor.listenTCP(24497, pb.PBServerFactory(self))
+ self.remote = None
+ self.response_queue = DeferredQueue()
+
+ @inlineCallbacks
+ def connect(self):
+ factory = pb.PBClientFactory()
+ reactor.connectTCP("10.111.101.206", 24498, factory)
+ self.remote = yield factory.getRootObject()
+ print 'connected'
+ yield self.remote.callRemote("setRemote", port=24496)
+
+ def remote_echo(self, pkt_type, pon, onu, port, crc, size, data):
+ print "Packet Type:", pkt_type
+ print "PON:", pon
+ print "ONU ID:", onu
+ print "Port:", port
+ print "CRC OK:", crc
+ print "Packet Size:", size
+ print "received:", hexify(data)
+ self.response_queue.put(data)
+
+ @inlineCallbacks
+ def send_omci(self, msg):
+ if isinstance(msg, Packet):
+ msg = str(msg)
+ try:
+ print ' sending:', msg
+ yield self.remote.callRemote("send_omci", 0, 0, 1, msg)
+ print 'msg sent'
+
+ except Exception, e:
+ print >> sys.stderr, 'Blew up:', str(e)
+
+ def receive(self):
+ return self.response_queue.get()
+
+
+@inlineCallbacks
+def chat():
+ proxy = OmciProxy()
+ yield proxy.connect()
+
+ tx_id = [0]
+ def get_tx_id():
+ tx_id[0] += 1
+ return tx_id[0]
+
+ if 0:
+ # MIB RESET
+ frame = OmciFrame(
+ transaction_id=get_tx_id(),
+ message_type=OmciMibReset.message_id,
+ omci_message=OmciMibReset(
+ entity_class=OntData.class_id
+ )
+ )
+ yield proxy.send_omci(hexify(str(frame)))
+
+ # MIB RESET RESPONSE
+ response = yield proxy.receive()
+ resp = OmciFrame(response)
+ resp.show()
+
+ if 0:
+ # GET ALL ALARMS
+ frame = OmciFrame(
+ transaction_id=get_tx_id(),
+ message_type=OmciGetAllAlarms.message_id,
+ omci_message=OmciGetAllAlarms(
+ entity_class=OntData.class_id,
+ entity_id=0
+ )
+ )
+ yield proxy.send_omci(hexify(str(frame)))
+
+ # MIB UPLOAD RESPONSE
+ response = yield proxy.receive()
+ resp = OmciFrame(response)
+ resp.show()
+
+ if 0:
+ # MIB UPLOAD
+ frame = OmciFrame(
+ transaction_id=get_tx_id(),
+ message_type=OmciMibUpload.message_id,
+ omci_message=OmciMibUpload(
+ entity_class=OntData.class_id
+ )
+ )
+ yield proxy.send_omci(hexify(str(frame)))
+
+ # MIB UPLOAD RESPONSE
+ response = yield proxy.receive()
+ resp = OmciFrame(response)
+ resp.show()
+
+ n_commands = resp.omci_message.number_of_commands
+ for seq_num in range(n_commands):
+ print 'seq_num', seq_num
+ frame = OmciFrame(
+ transaction_id=get_tx_id(),
+ message_type=OmciMibUploadNext.message_id,
+ omci_message=OmciMibUploadNext(
+ entity_class=OntData.class_id,
+ command_sequence_number=seq_num
+ )
+ )
+ yield proxy.send_omci(hexify(str(frame)))
+
+ response = yield proxy.receive()
+ print hexify(response)
+ # resp = OmciFrame(response)
+ # resp.show()
+
+
+ if 1:
+ # GET CIRCUIT PACK
+ frame = OmciFrame(
+ transaction_id=get_tx_id(),
+ message_type=OmciGet.message_id,
+ omci_message=OmciGet(
+ entity_class=CircuitPack.class_id,
+ entity_id=0x101,
+ attributes_mask=CircuitPack.mask_for('vendor_id')
+ )
+ )
+ yield proxy.send_omci(hexify(str(frame)))
+
+ # MIB UPLOAD RESPONSE
+ response = yield proxy.receive()
+ resp = OmciFrame(response)
+ resp.show()
+
+ yield asleep(1)
+ reactor.stop()
+
+
+if __name__ == '__main__':
+ reactor.callLater(0, chat)
+ reactor.run()
diff --git a/tests/utests/voltha/extensions/omci/test_omci.py b/tests/utests/voltha/extensions/omci/test_omci.py
index 1900508..2fcb75b 100644
--- a/tests/utests/voltha/extensions/omci/test_omci.py
+++ b/tests/utests/voltha/extensions/omci/test_omci.py
@@ -529,6 +529,44 @@
frame2 = OmciFrame(hex2raw(ref))
self.assertEqual(frame2, frame)
+ def test_mib_upload(self):
+ ref = '00304D0A000200000000000000000000' \
+ '00000000000000000000000000000000' \
+ '000000000000000000000028'
+ frame = OmciFrame(
+ transaction_id=48,
+ message_type=OmciMibUpload.message_id,
+ omci_message=OmciMibUpload(
+ entity_class=OntData.class_id
+ )
+ )
+ self.assertGeneratedFrameEquals(frame, ref)
+
+ def test_parsing_mib_upload_next_responses(self):
+ refs = [
+ '00042e0a000200000002000080000000000000000000000000000000000000000000000000000000000000283e0c62ee',
+ '00052e0a0002000000050101f0002f2f0520202020202020202020202020202020202020200000000000002808523170',
+ '00062e0a00020000000501010f80202020202020202020202020202020202020202000000000000000000028922568e4',
+ '00072e0a0002000000050104f00030300120202020202020202020202020202020202020200000000000002812bfa77d',
+ '00082e0a00020000000501040f802020202020202020202020202020202020202020000000000000000000282b03fcee',
+ '00092e0a0002000000050180f000f8f80120202020202020202020202020202020202020200000000000002881e385a2',
+ '000a2e0a00020000000501800f8020202020202020202020202020202020202020200000000000000000002888c5dbc2',
+ '000b2e0a0002000000060101f0002f054252434d12345678000000000000000000000000000c00000000002895471f4a',
+ '000c2e0a00020000000601010f004252434d0000000000000000000000000000000000000000000000000028742cbaea',
+ '000d2e0a000200000006010100f820202020202020202020202020202020202020200000000000000000002846978475',
+ '000e2e0a00020000000601010004000000000000000000000000000000000000000000000000000000000028a8403aea',
+ '000f2e0a0002000000060104f00030014252434d12345678000000000000000000000000000c000000000028723cf2ae',
+ '00102e0a00020000000601040f004252434d0000000000000000000000000000000000000000000000000028a958ebf8',
+ '00112e0a000200000006010400f8202020202020202020202020202020202020202000000800000000000028424cc847',
+ '00122e0a000200000006010400040000000000000000000000000000000000000000000000000000000000282bb79708',
+ '00132e0a0002000000060180f000f8014252434d12345678000000000000000000000000000c0000000000287834e722',
+ '00142e0a00020000000601800f004252434d000000000000000000000000000000000000000000000000002833d78834',
+ ]
+ for i, data in enumerate(refs):
+ frame = OmciFrame(hex2raw(data))
+ print 'Response', i
+ frame.show()
+
if __name__ == '__main__':
main()
diff --git a/voltha/extensions/omci/omci_entities.py b/voltha/extensions/omci/omci_entities.py
index cbeeec5..6c082ad 100644
--- a/voltha/extensions/omci/omci_entities.py
+++ b/voltha/extensions/omci/omci_entities.py
@@ -133,7 +133,28 @@
mandatory_operations = {OP.Get, OP.Set,
OP.GetAllAlarms, OP.GetAllAlarmsNext,
OP.MibReset, OP.MibUpload, OP.MibUploadNext}
- optional_operations = {}
+
+
+class Cardholder(EntityClass):
+ class_id = 5
+ attributes = [
+ ECA(ShortField("managed_entity_id", None), {AA.R}),
+ ECA(ByteField("actual_plugin_unit_type", None), {AA.R}),
+ ECA(ByteField("expected_plugin_unit_type", None), {AA.R, AA.W}),
+ ECA(ByteField("expected_port_count", None), {AA.R, AA.W},
+ optional=True),
+ ECA(StrFixedLenField("expected_equipment_id", None, 20), {AA.R, AA.W},
+ optional=True),
+ ECA(StrFixedLenField("actual_equipment_id", None, 20), {AA.R},
+ optional=True),
+ ECA(ByteField("protection_profile_pointer", None), {AA.R},
+ optional=True),
+ ECA(ByteField("invoke_protection_switch", None), {AA.R, AA.W},
+ optional=True),
+ ECA(ByteField("arc", None), {AA.R, AA.W}),
+ ECA(ByteField("arc_interval", None), {AA.R, AA.W}),
+ ]
+ mandatory_operations = {OP.Get, OP.Set}
class CircuitPack(EntityClass):
diff --git a/voltha/extensions/omci/omci_frame.py b/voltha/extensions/omci/omci_frame.py
index 5c8dd20..a762ad8 100644
--- a/voltha/extensions/omci/omci_frame.py
+++ b/voltha/extensions/omci/omci_frame.py
@@ -73,13 +73,21 @@
"omci_message", None, OmciGetAllAlarmsNextResponse), align=36),
lambda pkt:
pkt.message_type == OmciGetAllAlarmsNextResponse.message_id),
+
ConditionalField(FixedLenField(
PacketField("omci_message", None, OmciMibUpload), align=36),
+ lambda pkt: pkt.message_type == OmciMibUpload.message_id),
+ ConditionalField(FixedLenField(
+ PacketField("omci_message", None, OmciMibUploadResponse), align=36),
lambda pkt: pkt.message_type == OmciMibUploadResponse.message_id),
ConditionalField(FixedLenField(
PacketField("omci_message", None, OmciMibUploadNext), align=36),
lambda pkt:
- pkt.message_type == OmciMibUploadNextResponse.message_id),
+ pkt.message_type == OmciMibUploadNext.message_id),
+ ConditionalField(FixedLenField(
+ PacketField("omci_message", None, OmciMibUploadNextResponse), align=36),
+ lambda pkt: pkt.message_type == OmciMibUploadNextResponse.message_id),
+
ConditionalField(FixedLenField(
PacketField("omci_message", None, OmciMibReset), align=36),
lambda pkt: pkt.message_type == OmciMibReset.message_id),
diff --git a/voltha/extensions/omci/omci_messages.py b/voltha/extensions/omci/omci_messages.py
index 3710702..12956dc 100644
--- a/voltha/extensions/omci/omci_messages.py
+++ b/voltha/extensions/omci/omci_messages.py
@@ -86,7 +86,10 @@
indices = entity_class.attribute_indices_from_mask(attribute_mask)
data = {}
for index in indices:
- fld = entity_class.attributes[index]._fld
+ try:
+ fld = entity_class.attributes[index]._fld
+ except IndexError, e:
+ raise
s, value = fld.getfield(pkt, s)
data[fld.name] = value
return s, data
@@ -264,7 +267,8 @@
ShortField("object_entity_class", None),
ShortField("object_entity_id", 0),
ShortField("object_attributes_mask", None),
- OmciMaskedData("object_data")
+ OmciMaskedData("object_data", entity_class='object_entity_class',
+ attributes_mask='object_attributes_mask')
]