diff --git a/voltha/adapters/dpoe_onu/__init__.py b/voltha/adapters/dpoe_onu/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/voltha/adapters/dpoe_onu/__init__.py
diff --git a/voltha/adapters/dpoe_onu/dpoe_onu.py b/voltha/adapters/dpoe_onu/dpoe_onu.py
new file mode 100644
index 0000000..e1877e9
--- /dev/null
+++ b/voltha/adapters/dpoe_onu/dpoe_onu.py
@@ -0,0 +1,435 @@
+#
+# Copyright 2017 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+DPoE ONU device adapter
+"""
+
+import json
+
+from uuid import uuid4
+
+import structlog
+from zope.interface import implementer
+
+from binascii import hexlify
+
+from scapy.layers.inet import ICMP, IP
+from scapy.layers.l2 import Ether, Dot1Q
+from twisted.internet.defer import DeferredQueue, inlineCallbacks
+from twisted.internet import reactor
+
+from voltha.core.flow_decomposer import *
+from voltha.core.logical_device_agent import mac_str_to_tuple
+
+from voltha.adapters.interface import IAdapterInterface
+from voltha.protos.adapter_pb2 import Adapter, AdapterConfig
+from voltha.protos.device_pb2 import Port
+from voltha.protos.device_pb2 import DeviceType, DeviceTypes
+from voltha.protos.health_pb2 import HealthStatus
+from voltha.protos.common_pb2 import LogLevel, ConnectStatus
+from voltha.protos.common_pb2 import OperStatus, AdminState
+
+from voltha.protos.logical_device_pb2 import LogicalDevice, LogicalPort
+from voltha.protos.openflow_13_pb2 import ofp_desc, ofp_port, OFPPF_10GB_FD, \
+    OFPPF_FIBER, OFPPS_LIVE, ofp_switch_features, OFPC_PORT_STATS, \
+    OFPC_GROUP_STATS, OFPC_TABLE_STATS, OFPC_FLOW_STATS
+
+from scapy.packet import Packet, bind_layers
+from scapy.fields import StrField
+
+log = structlog.get_logger()
+
+from voltha.extensions.eoam.EOAM_TLV import AddStaticMacAddress, DeleteStaticMacAddress
+from voltha.extensions.eoam.EOAM_TLV import ClearStaticMacTable
+from voltha.extensions.eoam.EOAM_TLV import DeviceId
+from voltha.extensions.eoam.EOAM_TLV import ClauseSubtypeEnum
+from voltha.extensions.eoam.EOAM_TLV import RuleOperatorEnum
+from voltha.extensions.eoam.EOAM_TLV import FirmwareInfo
+
+from voltha.extensions.eoam.EOAM import EOAMPayload, CablelabsOUI
+from voltha.extensions.eoam.EOAM import DPoEOpcode_GetRequest, DPoEOpcode_SetRequest
+
+@implementer(IAdapterInterface)
+class DPoEOnuAdapter(object):
+
+    name = 'dpoe_onu'
+
+    supported_device_types = [
+        DeviceType(
+            id='dpoe_onu',
+            adapter=name,
+            accepts_bulk_flow_update=True
+        )
+    ]
+
+    def __init__(self, adapter_agent, config):
+        self.adapter_agent = adapter_agent
+        self.config = config
+        self.descriptor = Adapter(
+            id=self.name,
+            vendor='Sumitomo Electric, Inc.',
+            version='0.1',
+            config=AdapterConfig(log_level=LogLevel.INFO)
+        )
+        self.incoming_messages = DeferredQueue()
+
+    def start(self):
+        log.debug('starting')
+        log.info('started')
+
+    def stop(self):
+        log.debug('stopping')
+        log.info('stopped')
+
+    def adapter_descriptor(self):
+        return self.descriptor
+
+    def device_types(self):
+        return DeviceTypes(items=self.supported_device_types)
+
+    def health(self):
+        return HealthStatus(state=HealthStatus.HealthState.HEALTHY)
+
+    def change_master_state(self, master):
+        raise NotImplementedError()
+
+    def adopt_device(self, device):
+        log.info('adopt-device', device=device)
+        reactor.callLater(0.1, self._onu_device_activation, device)
+        return device
+
+    @inlineCallbacks
+    def _onu_device_activation(self, device):
+        # first we verify that we got parent reference and proxy info
+        assert device.parent_id
+        assert device.proxy_address.device_id
+        assert device.proxy_address.channel_id
+
+        # TODO: For now, pretend that we were able to contact the device and obtain
+        # additional information about it.  Should add real message.
+        device.vendor = 'Sumitomo Electric, Inc.'
+        device.model = '10G EPON ONU'
+        device.hardware_version = 'fa161020'
+        device.firmware_version = '16.12.02'
+        device.software_version = '1.0'
+        device.serial_number = uuid4().hex
+        device.connect_status = ConnectStatus.REACHABLE
+        self.adapter_agent.update_device(device)
+
+        # then shortly after we create some ports for the device
+        uni_port = Port(
+            port_no=2,
+            label='UNI facing Ethernet port',
+            type=Port.ETHERNET_UNI,
+            admin_state=AdminState.ENABLED,
+            oper_status=OperStatus.ACTIVE
+        )
+        self.adapter_agent.add_port(device.id, uni_port)
+        self.adapter_agent.add_port(device.id, Port(
+            port_no=1,
+            label='PON port',
+            type=Port.PON_ONU,
+            admin_state=AdminState.ENABLED,
+            oper_status=OperStatus.ACTIVE,
+            peers=[
+                Port.PeerPort(
+                    device_id=device.parent_id,
+                    port_no=device.parent_port_no
+                )
+            ]
+        ))
+
+        # TODO adding vports to the logical device shall be done by agent?
+        # then we create the logical device port that corresponds to the UNI
+        # port of the device
+
+        # obtain logical device id
+        parent_device = self.adapter_agent.get_device(device.parent_id)
+        logical_device_id = parent_device.parent_id
+        assert logical_device_id
+
+        # we are going to use the proxy_address.channel_id as unique number
+        # and name for the virtual ports, as this is guaranteed to be unique
+        # in the context of the OLT port, so it is also unique in the context
+        # of the logical device
+        port_no = device.proxy_address.channel_id
+        cap = OFPPF_10GB_FD | OFPPF_FIBER
+        self.adapter_agent.add_logical_port(logical_device_id, LogicalPort(
+            id=str(port_no),
+            ofp_port=ofp_port(
+                port_no=port_no,
+                hw_addr=mac_str_to_tuple(device.mac_address),
+                name='uni-{}'.format(port_no),
+                config=0,
+                state=OFPPS_LIVE,
+                curr=cap,
+                advertised=cap,
+                peer=cap,
+                curr_speed=OFPPF_10GB_FD,
+                max_speed=OFPPF_10GB_FD
+            ),
+            device_id=device.id,
+            device_port_no=uni_port.port_no
+        ))
+
+        # simulate a proxied message sending and receving a reply
+        reply = yield self._message_exchange(device)
+
+        # and finally update to "ACTIVE"
+        device = self.adapter_agent.get_device(device.id)
+        device.oper_status = OperStatus.ACTIVE
+        self.adapter_agent.update_device(device)
+
+    def abandon_device(self, device):
+        raise NotImplementedError(0
+                                  )
+    def deactivate_device(self, device):
+        raise NotImplementedError()
+
+    def update_flows_bulk(self, device, flows, groups):
+        log.info('########################################')
+        log.info('bulk-flow-update', device_id=device.id,
+                 flows=flows, groups=groups)
+        assert len(groups.items) == 0, "Cannot yet deal with groups"
+
+        Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()}
+        Operator = {v: k for k, v in RuleOperatorEnum.iteritems()}
+
+        for flow in flows.items:
+            in_port = get_in_port(flow)
+            assert in_port is not None
+
+            precedence = 255 - min(flow.priority / 256, 255)
+
+            if in_port == 2:
+                log.info('#### Downstream Rule ####')
+                dn_req = EOAMPayload(body=CablelabsOUI() /
+                                     DPoEOpcode_SetRequest())
+
+                for field in get_ofb_fields(flow):
+
+                    if field.type == ETH_TYPE:
+                        _type = field.eth_type
+                        log.info('#### field.type == ETH_TYPE ####',field_type=_type)
+
+                    elif field.type == IP_PROTO:
+                        _proto = field.ip_proto
+                        log.info('#### field.type == IP_PROTO ####')
+                        pass  # construct ip_proto based condition here
+
+                    elif field.type == IN_PORT:
+                        _port = field.port
+                        log.info('#### field.type == IN_PORT ####', port=_port)
+                        pass  # construct in_port based condition here
+
+                    elif field.type == VLAN_VID:
+                        _vlan_vid = field.vlan_vid & 0xfff
+                        log.info('#### field.type == VLAN_VID ####', vlan=_vlan_vid)
+
+                    elif field.type == VLAN_PCP:
+                        _vlan_pcp = field.vlan_pcp
+                        log.info('#### field.type == VLAN_PCP ####', pcp=_vlan_pcp)
+                        pass  # construct VLAN PCP based filter condition here
+
+                    elif field.type == UDP_DST:
+                        _udp_dst = field.udp_dst
+                        log.info('#### field.type == UDP_DST ####')
+                        pass  # construct UDP SDT based filter here
+
+                    elif field.type == IPV4_DST:
+                        _ipv4_dst = field.ipv4_dst
+                        log.info('#### field.type == IPV4_DST ####')
+                        pass
+
+                    else:
+                        log.info('#### field.type == NOT IMPLEMENTED!! ####')
+                        raise NotImplementedError('field.type={}'.format(
+                            field.type))
+
+                for action in get_actions(flow):
+
+                    if action.type == OUTPUT:
+                        log.info('#### action.type == OUTPUT ####')
+
+                    elif action.type == POP_VLAN:
+                        log.info('#### action.type == POP_VLAN ####')
+                        pass  # construct vlan pop command here
+
+                    elif action.type == PUSH_VLAN:
+                        log.info('#### action.type == PUSH_VLAN ####')
+                        if action.push.ethertype != 0x8100:
+                            log.error('unhandled-tpid',
+                                      ethertype=action.push.ethertype)
+
+                    elif action.type == SET_FIELD:
+                        log.info('#### action.type == SET_FIELD ####')
+                        assert (action.set_field.field.oxm_class ==
+                                ofp.OFPXMC_OPENFLOW_BASIC)
+                        field = action.set_field.field.ofb_field
+                        if field.type == VLAN_VID:
+                            pass
+                        else:
+                            log.error('unsupported-action-set-field-type',
+                                      field_type=field.type)
+                    else:
+                        log.error('UNSUPPORTED-ACTION-TYPE',
+                                  action_type=action.type)
+
+                # send message
+                log.info('ONU-send-proxied-message')
+#                self.adapter_agent.send_proxied_message(device.proxy_address, dn_req)
+
+
+            elif in_port == 1:
+                # Upstream rule
+                log.info('#### Upstream Rule ####')
+
+                #### Loop through fields again...
+
+                for field in get_ofb_fields(flow):
+
+                    if field.type == ETH_TYPE:
+                        _type = field.eth_type
+                        log.info('#### field.type == ETH_TYPE ####', in_port=in_port,
+                                 match=_type)
+
+                    elif field.type == IP_PROTO:
+                        _proto = field.ip_proto
+                        log.info('#### field.type == IP_PROTO ####', in_port=in_port,
+                                 ip_proto=ip_proto)
+
+                    elif field.type == IN_PORT:
+                        _port = field.port
+                        log.info('#### field.type == IN_PORT ####')
+                        pass  # construct in_port based condition here
+
+                    elif field.type == VLAN_VID:
+                        _vlan_vid = field.vlan_vid & 0xfff
+                        log.info('#### field.type == VLAN_VID ####')
+
+                    elif field.type == VLAN_PCP:
+                        _vlan_pcp = field.vlan_pcp
+                        log.info('#### field.type == VLAN_PCP ####')
+                        pass  # construct VLAN PCP based filter condition here
+
+                    elif field.type == UDP_DST:
+                        _udp_dst = field.udp_dst
+                        log.info('#### field.type == UDP_DST ####')
+
+                    else:
+                        raise NotImplementedError('field.type={}'.format(
+                            field.type))
+
+                for action in get_actions(flow):
+
+                    if action.type == OUTPUT:
+                        log.info('#### action.type == OUTPUT ####')
+
+                    elif action.type == POP_VLAN:
+                        log.info('#### action.type == POP_VLAN ####')
+                        pass  # construct vlan pop command here
+
+                    elif action.type == PUSH_VLAN:
+                        log.info('#### action.type == PUSH_VLAN ####')
+                        if action.push.ethertype != 0x8100:
+                            log.error('unhandled-ether-type',
+                                      ethertype=action.push.ethertype)
+
+                    elif action.type == SET_FIELD:
+                        log.info('#### action.type == SET_FIELD ####')
+                        assert (action.set_field.field.oxm_class ==
+                                ofp.OFPXMC_OPENFLOW_BASIC)
+                        field = action.set_field.field.ofb_field
+                        if field.type == VLAN_VID:
+                            pass
+                        else:
+                            log.error('unsupported-action-set-field-type',
+                                      field_type=field.type)
+
+                    else:
+                        log.error('UNSUPPORTED-ACTION-TYPE',
+                                  action_type=action.type)
+
+            else:
+                raise Exception('Port should be 1 or 2 by our convention')
+
+    def update_flows_incrementally(self, device, flow_changes, group_changes):
+        raise NotImplementedError()
+
+    def send_proxied_message(self, proxy_address, msg):
+        raise NotImplementedError()
+
+    def receive_proxied_message(self, proxy_address, msg):
+        log.debug('receive-proxied-message',
+                  proxy_address=proxy_address, msg=msg)
+        self.incoming_messages.put(msg)
+
+    @inlineCallbacks
+    def _message_exchange(self, device):
+
+        # register for receiving async messages
+        self.adapter_agent.register_for_proxied_messages(device.proxy_address)
+
+        # reset incoming message queue
+        while self.incoming_messages.pending:
+            _ = yield self.incoming_messages.get()
+
+        # construct message
+        msg = EOAMPayload(body=CablelabsOUI() /
+                          DPoEOpcode_GetRequest() /
+                          DeviceId()
+                          )
+
+        # send message
+        log.info('ONU-send-proxied-message')
+        self.adapter_agent.send_proxied_message(device.proxy_address, msg)
+
+        # wait till we detect incoming message
+        yield self.incoming_messages.get()
+
+        # construct install of igmp query address
+        msg = EOAMPayload(body=CablelabsOUI() /
+                          DPoEOpcode_SetRequest() /
+                          AddStaticMacAddress(mac='01:00:5e:00:00:01')
+                          )
+
+        # send message
+        log.info('ONU-send-proxied-message')
+        self.adapter_agent.send_proxied_message(device.proxy_address, msg)
+
+        # wait till we detect incoming message
+        yield self.incoming_messages.get()
+
+        # construct install of igmp query address
+        msg = EOAMPayload(body=CablelabsOUI() /
+                          DPoEOpcode_GetRequest() /
+                          FirmwareInfo()
+                          )
+
+        # send message
+        log.info('ONU-send-proxied-message')
+        self.adapter_agent.send_proxied_message(device.proxy_address, msg)
+
+        # wait till we detect incoming message
+        yield self.incoming_messages.get()
+
+        # by returning we allow the device to be shown as active, which
+        # indirectly verified that message passing works
+
+    def receive_packet_out(self, logical_device_id, egress_port_no, msg):
+        log.info('packet-out', logical_device_id=logical_device_id,
+                 egress_port_no=egress_port_no, msg_len=len(msg))
diff --git a/voltha/adapters/dpoe_onu/eoam_config.py b/voltha/adapters/dpoe_onu/eoam_config.py
new file mode 100644
index 0000000..b69770b
--- /dev/null
+++ b/voltha/adapters/dpoe_onu/eoam_config.py
@@ -0,0 +1,358 @@
+#!/usr/bin/env python
+#--------------------------------------------------------------------------#
+# Copyright (C) 2015 - 2016 by Tibit Communications, Inc.                  #
+# All rights reserved.                                                     #
+#                                                                          #
+#    _______ ____  _ ______                                                #
+#   /_  __(_) __ )(_)_  __/                                                #
+#    / / / / __  / / / /                                                   #
+#   / / / / /_/ / / / /                                                    #
+#  /_/ /_/_____/_/ /_/                                                     #
+#                                                                          #
+#--------------------------------------------------------------------------#
+""" EOAM protocol implementation in scapy """
+
+TIBIT_VERSION_NUMBER = '1.1.2'
+
+import time
+import logging
+import argparse
+import sys
+import inspect
+
+logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
+from scapy.all import Dot1Q
+from scapy.all import sniff
+from scapy.all import IP, UDP
+from scapy.packet import Packet, bind_layers
+from scapy.fields import StrField
+from scapy.layers.l2 import Ether
+from scapy.main import interact
+from scapy.sendrecv import sendp
+from scapy.sendrecv import srp1
+from scapy.config import conf
+conf.verb = None
+
+import fcntl, socket, struct # for get hw address
+
+# TODO should remove import *
+from EOAM_TLV import *
+
+EOAM_MULTICAST_ADDRESS = '01:80:c2:00:00:02'
+IGMP_MULTICAST_ADDRESS = '01:00:5e:00:00:01'   # for test
+
+class EOAM():
+    """ EOAM frame layer """
+    def __init__(self, ctag=None, dryrun=False, stag=None,
+                 verbose=False, etype='8809',
+                 dst=EOAM_MULTICAST_ADDRESS,
+                 hexdump=False, interface='eth0',
+                 sleep=1.0):
+        self.verbose = verbose
+        self.dst = dst
+        self.dryrun = dryrun
+        self.hexdump = hexdump
+        self.interface = interface
+        self.etype = int(etype, 16)
+        self.stag = stag
+        self.ctag = ctag
+        self.sleep = sleep
+        if (self.verbose == True):
+            print("=== Settings ================")
+            print("ctag      = %s" % self.ctag)
+            print("stag      = %s" % self.stag)
+            print("dst       = %s" % self.dst)
+            print("dryrun    = %s" % self.dryrun)
+            print("hexdump   = %s" % self.hexdump)
+            print("interface = %s" % self.interface)
+            print("etype     = 0x%04x" % self.etype)
+            print("verbose   = %s" % self.verbose)
+            print("=== END Settings ============")
+
+    def send_frame(self, frame_body):
+        PACKET = Ether()
+        PACKET.length = 64
+        PACKET.dst = self.dst
+        PACKET.src = self.getHwAddr(self.interface)
+        if self.stag:
+            # WARNING: September/2016: This should be 0x88a8, but the Intel 10G
+            # hardware I am currently using does not support receiving a TPID of
+            # 0x88a8. So, I send double CTAGs, and I usually set this to 0x8100.
+            # (NOTE: The Intel hardware can send a TPID of 0x88a8)
+            PACKET.type = 0x8100
+            if self.ctag:
+                PACKET/=Dot1Q(type=0x8100,vlan=int(self.stag))
+                PACKET/=Dot1Q(type=self.etype,vlan=int(self.ctag))
+            else:
+                PACKET/=Dot1Q(type=self.etype,vlan=int(self.stag))
+        else:
+            if self.ctag:
+                PACKET.type = 0x8100
+                PACKET/=Dot1Q(type=self.etype,vlan=int(self.ctag))
+            else:
+                PACKET.type = self.etype
+#            PACKET/=Dot1Q(type=self.etype, vlan=int(self.ctag))
+        PACKET/=SlowProtocolsSubtype()/FlagsBytes()/OAMPDU()
+        PACKET/=frame_body
+        PACKET/=EndOfPDU()
+        if (self.verbose == True):
+            PACKET.show()
+            print '###[ Frame Length %d (before padding) ]###' % len(PACKET)
+        if (self.hexdump == True):
+            print hexdump(PACKET)
+        if (self.dryrun != True):
+            sendp(PACKET, iface=self.interface, verbose=self.verbose)
+            time.sleep(self.sleep)
+        return PACKET
+
+    def get_request(self, TLV):
+        return self.send_frame(CablelabsOUI()/DPoEOpcode_GetRequest()/TLV)
+
+    def set_request(self, TLV):
+        return self.send_frame(CablelabsOUI()/DPoEOpcode_SetRequest()/TLV)
+
+    def send_multicast_register(self, TLV):
+        '''
+        Note, for mulicast, the standard specifies a register message
+        with ActionFlags of either Register or Deregister
+        '''
+        return self.send_frame(CablelabsOUI()/DPoEOpcode_MulticastRegister()/TLV)
+
+    def set_request_broadcom(self, TLV):
+        return self.send_frame(BroadcomOUI()/DPoEOpcode_SetRequest()/TLV)
+
+    def getHwAddr(self, ifname):
+        if (not self.dryrun):
+            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+            info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
+        else:
+            info = range(1, 24)
+            info[18:24] = ['0','1','2','3','4','5']
+
+        return ':'.join(['%02x' % ord(char) for char in info[18:24]])
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-d', '--dst', dest='dst', action='store', default=EOAM_MULTICAST_ADDRESS,
+                        help='MAC destination (default: %s)' % EOAM_MULTICAST_ADDRESS)
+    parser.add_argument('-e', '--etype', dest='etype', action='store', default='8809',
+                        help='EtherType value (default: 0x8809)')
+    parser.add_argument('-i', '--interface', dest='interface', action='store', default='eth0',
+                        help='ETH interface to send (default: eth0)')
+    parser.add_argument('-s', '--stag', dest='stag', action='store', default=None,
+                        help='STAG value (default: None)')
+    parser.add_argument('-c', '--ctag', dest='ctag', action='store', default=None,
+                        help='CTAG value (default: None)')
+    parser.add_argument('-p', '--sleep', dest='sleep', action='store', default='1.0', type=float,
+                        help='SLEEP time after frame (default: 0.5 secs)')
+    parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False,
+                        help='verbose frame print out')
+    parser.add_argument('-x', '--hexdump', dest='hexdump', action='store_true', default=False,
+                        help='Hexdump the frame')
+    parser.add_argument('-y', '--dryrun', dest='dryrun', action='store_true', default=False,
+                        help='Dry run test, dont send - just print')
+
+    parser.add_argument('-t', '--test', dest='test', action='store_true', default=False,
+                        help='Run commands under test')
+    parser.add_argument('-r', '--critical', dest='critical', action='store_true', default=False,
+                        help='Send the critical OAM set of set_request()')
+    parser.add_argument('-ta', '--test_add', dest='test_add', action='store_true', default=False,
+                        help='Run commands under test')
+    parser.add_argument('-td', '--test_del', dest='test_del', action='store_true', default=False,
+                        help='Run commands under test')
+    parser.add_argument('-tc', '--test_clr', dest='test_clr', action='store_true', default=False,
+                        help='Run commands under test')
+
+    args = parser.parse_args()
+
+    if (args.dryrun == True):
+        args.sleep = 0.0
+
+    eoam = EOAM(
+        dryrun=args.dryrun,
+        dst=args.dst,
+        etype=args.etype,
+        hexdump=args.hexdump,
+        interface=args.interface,
+        stag=args.stag,
+        ctag=args.ctag,
+        verbose=args.verbose,
+        )
+
+    if (not args.critical
+        and not args.test
+        and not args.test_add
+        and not args.test_del
+        and not args.test_clr):
+        print 'WARNING: *** No frames sent, please specify \'test\' or \'critical\', etc.  See --help'
+
+    # Critical OAM Messages
+    if (args.critical == True):
+
+        # OAM GET Requests
+        print 'GET DeviceId and MAX Logical Links Message'
+        eoam.get_request(DeviceId()/MaxLogicalLinks())
+
+        print 'SET Report Thresholds Message'
+        eoam.set_request(ReportThresholdsSet())
+
+        print 'SET OAM Frame Rate Message'
+        eoam.set_request(OamFrameRateSet())
+
+        print 'GET multiple - Device and Manufacturing Info'
+        eoam.get_request(DONUObject()/DeviceId()/MaxLogicalLinks()/
+                              FirmwareInfo()/ChipsetInfo()/NumberOfNetworkPorts()/NumberOfS1Interfaces())
+
+        print 'GET - LLID Queue Configuration'
+        eoam.get_request(DONUObject()/LLIDQueueConfiguration())
+
+        print 'GET - ONU Manufacturer Organization Name'
+        eoam.get_request(DONUObject()/OnuManufacturerOrganizationName())
+
+        print 'GET - ONU Firmware Mfg Time Varying Controls'
+        eoam.get_request(DONUObject()/FirmwareMfgTimeVaryingControls())
+
+        print 'GET - ONU Vendor Name'
+        eoam.get_request(DONUObject()/VendorName())
+
+        print 'GET - ONU Model Number'
+        eoam.get_request(DONUObject()/ModelNumber())
+
+        print 'GET - ONU Hardware Version'
+        eoam.get_request(DONUObject()/HardwareVersion())
+
+        print 'SET - Clear Port Ingress Rules -- Network Port Object'
+        eoam.set_request(NetworkPortObject()/ClearPortIngressRules())
+
+        print 'SET - Clear Port Ingress Rules -- User Port Object'
+        eoam.set_request(UserPortObject()/ClearPortIngressRules())
+
+        print 'SET - Broadcom Specific TLVs'
+        eoam.set_request_broadcom(Broadcom07_7F_F1_Set01()/Broadcom07_7F_F1_Set02()/
+                                       Broadcom07_7F_F1_Set03()/Broadcom07_7F_F1_Set04())
+
+        print 'SET - Multicast Register Message 01'
+        eoam.send_multicast_register(MulticastRegisterSetSumitomo01())
+
+        print 'SET - Multicast Register Message 02'
+        eoam.send_multicast_register(MulticastRegisterSetSumitomo02())
+
+        print 'SET - Custom Field EtherType'
+        eoam.set_request(UserPortObject()/CustomFieldEtherType())
+
+        print 'SET - Custom Field Generic L3'
+        eoam.set_request(UserPortObject()/CustomFieldGenericL3())
+
+        print 'SET - MAC Learning MIN/MAX/Age Limit -- User Port Object'
+        eoam.set_request(UserPortObject()/MacLearningMaxAllowedSet()/DynamicAddressAgeLimitSet()/
+                              SourceAddressAdmissionControlSet()/MacLearningMinGuaranteeSet())
+
+        print 'SET - MAC Learning/Flooding/Local Switching -- D-ONU Port Object'
+        eoam.set_request(DONUObject()/MacLearningAggregateLimitSet()/FloodUnknownSet()/LocalSwitchingSet())
+
+        print 'SET - Report Thresholds -- Unicast Logical Link'
+        eoam.set_request(UnicastLogicalLink()/UnicastLogicalLinkReportThresholdsSet())
+
+        print 'SET - Port Ingress Rule -- Network Port Object -- Precedence 12'
+        eoam.set_request(NetworkPortObject()/
+                              PortIngressRuleHeader(precedence=12)/
+                              PortIngressRuleClauseMatchLength01(operator=1)/
+                              PortIngressRuleResultForward()/
+                              PortIngressRuleResultQueue(objecttype=0x0003)/
+                              PortIngressRuleTerminator()/
+                              AddPortIngressRule())
+
+        print 'SET - Port Ingress Rule -- User Port Object -- Precedence 13'
+        eoam.set_request(UserPortObject()/
+                              PortIngressRuleHeader(precedence=13)/
+                              PortIngressRuleClauseMatchLength00(fieldcode=1, operator=7)/
+                              PortIngressRuleResultQueue(objecttype=0x0002)/
+                              PortIngressRuleTerminator()/
+                              AddPortIngressRule())
+
+        print 'SET - Port Ingress Rule -- User Port Object -- Precedence 7 Discard 01'
+        eoam.set_request(UserPortObject()/
+                              PortIngressRuleHeader(precedence=7)/
+                              PortIngressRuleClauseMatchLength06(fieldcode=1, operator=1)/
+                              PortIngressRuleResultDiscard()/
+                              PortIngressRuleTerminator()/
+                              AddPortIngressRule())
+
+
+        print 'SET - Port Ingress Rule -- User Port Object -- Precedence 7 Discard 02'
+        eoam.set_request(UserPortObject()/
+                              PortIngressRuleHeader(precedence=7)/
+                              PortIngressRuleClauseMatchLength06(fieldcode=1, operator=1, match5=0x02)/
+                              PortIngressRuleClauseMatchLength02(fieldcode=0x19, operator=1, match=0x8889)/
+                              PortIngressRuleClauseMatchLength01(fieldcode=0x1a, operator=1, match=0x03)/
+                              PortIngressRuleResultDiscard()/
+                              PortIngressRuleTerminator()/
+                              AddPortIngressRule())
+
+        print 'GET - D-ONU Object -- Firmware Filename'
+        eoam.set_request(DONUObject()/FirmwareFilename())
+
+        print 'SET - User Port Object 0 -- Broadcom Specific TLVs'
+        eoam.set_request_broadcom(UserPortObject(number=0)/Broadcom07_7F_F6_Set())
+
+        print 'SET - User Port Object 1 -- Broadcom Specific TLVs'
+        eoam.set_request_broadcom(UserPortObject(number=1)/Broadcom07_7F_F6_Set())
+
+        print 'SET - User Port Object 0 -- Clause 30 Attributes -- MAC Enable'
+        eoam.set_request(UserPortObject()/Clause30AttributesMacEnable())
+
+        print 'SET - IPMC Forwarding Rule Configuration'
+        eoam.set_request(IpmcForwardingRuleConfiguration())
+
+        print 'SET - Enable User Traffic -- Unicast Logical Link'
+        eoam.set_request(UnicastLogicalLink()/EnableUserTraffic())
+
+    if (args.test == True):
+        print 'SET - Multicast Register Message 01'
+        eoam.send_multicast_register(MulticastRegisterSet(MulticastLink=0x3ff0, UnicastLink=0x120f))
+
+        #print 'SET - Multicast Deregister Message 02'
+        eoam.send_multicast_register(MulticastRegisterSet(ActionFlags="Deregister",MulticastLink=0x3ff0, UnicastLink=0x120f))
+
+    if (args.test_clr == True):
+        print 'SET Clear Static MAC Table -- User Port Object'
+        eoam.set_request(ClearStaticMacTable())
+
+    elif (args.test_add == True):
+        print 'SET Add Static MAC Address -- User Port Object'
+        eoam.set_request(AddStaticMacAddress(mac=IGMP_MULTICAST_ADDRESS))
+
+    elif (args.test_del == True):
+        print 'SET Delete Static MAC Address -- User Port Object'
+        eoam.set_request(DeleteStaticMacAddress(mac=IGMP_MULTICAST_ADDRESS))
+
+
+
+    # EXTERNAL OAM LIB TESTING
+    #import tboam
+    #tboam.get_request(f.branch, f.leaf)
+    #print 'SET - User Port Object 1 -- Broadcom Specific TLVs'
+    #f = eoam.set_request_broadcom(UserPortObject(number=1)/Broadcom07_7F_F6_Set())
+    #print("=== receive frame ===========")
+    #Now, pretend I just received this frame.
+    #f.show()
+    #tboam.set_request(f.branch, f.leaf)
+
+    # Examples
+    #oam_frame = eoam.get_request(UserPortObject()/LoopbackEnable())
+    #oam_frame = eoam.get_reqeust(UserPortObject()/LoopbackDisable())
+    #oam_frame = eoam.set_request(UserPortObject()/LoopbackEnable())
+    #oam_frame = eoam.set_request(UnicastLogicalLink()/AlarmReportingSet())
+    #oam_frame = eoam.get_request(UserPortObject()/BytesDropped())
+    #oam_frame = eoam.get_request(UserPortObject()/TxBytesUnused())
+    #print 'GET -- User Port Object -- Rx Frame 512-1023'
+    #oam_frame = eoam.get_request(UserPortObject()/RxFrame_512_1023())
+    #print 'GET -- User Port Object -- Tx Frame 512-1023'
+    #oam_frame = eoam.get_request(UserPortObject()/TxFrame_512_1023())
+    #oam_frame = eoam.get_request(NetworkPortObject()/BytesDropped())
+    #oam_frame = eoam.get_request(NetworkPortObject()/TxBytesUnused())
+    #print 'GET -- Network Port Object -- Rx Frame 512-1023'
+    #oam_frame = eoam.get_request(NetworkPortObject()/RxFrame_512_1023())
+    #print 'GET -- Network Port Object -- Tx Frame 512-1023'
+    #oam_frame = eoam.get_request(NetworkPortObject()/TxFrame_512_1023())
diff --git a/voltha/adapters/dpoe_onu/mgmt_json.c b/voltha/adapters/dpoe_onu/mgmt_json.c
new file mode 100644
index 0000000..4391a4f
--- /dev/null
+++ b/voltha/adapters/dpoe_onu/mgmt_json.c
@@ -0,0 +1,2202 @@
+/*--------------------------------------------------------------------------*/
+/* Copyright (C) 2015 - 2016 by Tibit Communications, Inc.                  */
+/* All rights reserved.                                                     */
+/*                                                                          */
+/*    _______ ____  _ ______                                                */
+/*   /_  __(_) __ )(_)_  __/                                                */
+/*    / / / / __  / / / /                                                   */
+/*   / / / / /_/ / / / /                                                    */
+/*  /_/ /_/_____/_/ /_/                                                     */
+/*                                                                          */
+/*--------------------------------------------------------------------------*/
+/* PROPRIETARY NOTICE                                                       */
+/* This Software consists of confidential information.                      */
+/* Trade secret law and copyright law protect this Software.                */
+/* The above notice of copyright on this Software does not indicate         */
+/* any actual or intended publication of such Software.                     */
+/*--------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <common.h>
+#include <cli.h>
+#include <command.h>
+#include <assert.h>
+
+#include "tb_dbug.h"
+#include "tb_port.h"
+#include "tb_util.h"
+#include "tb_global.h"
+#include "tb_types.h"
+
+#include "cli_version.h"
+#include "mgmt_json.h"
+#include "brdg.h"
+#include "os_interface.h"
+#include "jsmn.h"
+
+#include "olt_fsm.h"
+#include "onu_fsm.h"
+#include "eth_fsm.h"
+#include "hal_llid.h"
+#include "hal_frame.h"
+#include "switching.h"
+
+#include "ieee_802.3.h"
+
+
+/*--- global variables -----------------------------------------------------*/
+static tb_pkt_deprec_t fake_frame;      /* for commands from the CLI */
+extern const char *brdg_stat_name_lower[];
+extern const char *brdg_stat_total_lower[];
+static bool command_line_json = false;
+
+/*--- definitions ----------------------------------------------------------*/
+#define FRAME_CRC_SIZE           4
+#define VLAN_HEADER_BYTES        4
+
+#define START_OF_JSON_VLAN       (27 + (VLAN_HEADER_BYTES))
+#define START_OF_JSON_UNTAGGED   (27)
+#define COPY_TYPE                0x636f7079 // 'copy'
+#define DNLD_TYPE                0x646e6c64 // 'dnld'
+#define JSON_TYPE                0x6a736f6e     /* ASCII HEX 'json' */
+#define JSON_MAX_INTERFACES      5
+typedef enum json_string_print { APPEND, APPEND_AND_FLUSH, APPEND_AND_FLUSH_CR,
+    RESET
+} json_string_print_t;
+
+/*--- function prototypes --------------------------------------------------*/
+void hw_reset(void);
+int set_sernum_and_mac_address(unsigned int);
+static int dump(const char *js, jsmntok_t * t, size_t count, int indent);
+static int remove_backslashes(char *working, uint8_t * p_buffer, unsigned int length);
+
+/*--- more globals ---------------------------------------------------------*/
+static char global_json_string[SIZE_OF_JSON_STRING] = { '\0' };
+
+static char operation[SIZE_OF_OPERATION] = { '\0' };
+static char location[SIZE_OF_ADDRESS] = { '\0' };
+static char value[SIZE_OF_VALUE] = { '\0' };
+static char llid[SIZE_OF_LLID] = { '\0' };
+static char macblock[SIZE_OF_MACBLOCK] = { '\0' };
+static char itype[SIZE_OF_ITYPE] = { '\0' };
+static char iinst[SIZE_OF_IINST] = { '\0' };
+static char mac[MAC_STR_LEN] = { '\0' };
+static char swr[SIZE_OF_SWR] = { '\0' };
+static char cmd[SIZE_OF_CMD] = { '\0' };
+
+#define SVID_STR_LEN 5
+#define CVID_STR_LEN 5
+static char svid[SVID_STR_LEN] = { '\0' };
+static char cvid[CVID_STR_LEN] = { '\0' };
+
+static mac_address mac_addr;
+#define CIR_STR_LEN 12
+#define EIR_STR_LEN 12
+static char cir[CIR_STR_LEN] = { '\0' };
+static char eir[EIR_STR_LEN] = { '\0' };
+
+#define CODE_STR_LEN 5
+static char code[CODE_STR_LEN] = { '\0' };
+
+#define TPID_STR_LEN 5
+static char tpid[TPID_STR_LEN] = { '\0' };
+
+#define VID_STR_LEN 5
+static char vid[VID_STR_LEN] = { '\0' };
+
+#define MODE_STR_LEN 9
+static char mode[MODE_STR_LEN] = { '\0' };
+
+#define TAG_MODE_STR_LEN 5
+static char tag_mode[TAG_MODE_STR_LEN] = { '\0' };
+
+/*--- more function prototypes ---------------------------------------------*/
+static int process_copy(const uint8_t *, uint32);
+static int process_dnld(const uint8_t *, uint32);
+static int process_json(tb_pkt_deprec_t *);
+static int json_error(tb_pkt_deprec_t *, brdg_return_t);
+static int json_version(tb_pkt_deprec_t *);
+static int json_interfaces(tb_pkt_deprec_t *);
+static int json_links(tb_pkt_deprec_t *, char *, tb_ifc_inst_t);
+static int json_register_read(tb_pkt_deprec_t *, unsigned int address);
+static int json_register_write(tb_pkt_deprec_t *, unsigned int address, unsigned int value);
+static int json_stats(tb_pkt_deprec_t *, unsigned int llid, unsigned int macblock);
+static tb_rc json_tag_mode_get(tb_pkt_deprec_t * rx_frame);
+static tb_rc json_tag_mode_set(tb_pkt_deprec_t * rx_frame, char * tag_mode);
+static tb_rc json_fec_set(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key, bool);
+static tb_rc json_fec_get(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key);
+static tb_rc json_sla_set(tb_pkt_deprec_t * rx_frame, lsm_link_key_t * link_key,
+                          lsm_link_sla_spec_t * sla_spec);
+static tb_rc json_sla_get(tb_pkt_deprec_t * rx_frame, lsm_link_key_t * link_key,
+                          lsm_link_sla_spec_t * sla_spec);
+static tb_rc json_flows_add(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key,
+                            sw_rec_key_t * sw_rec_key, port_vlan_op_cfg_t port_vlan_op_cfg);
+static tb_rc json_flows_delete(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key,
+                              sw_rec_key_t * sw_rec_key);
+static tb_rc json_flows_get(tb_pkt_deprec_t * rx_frame);
+static tb_rc json_mode_set(tb_pkt_deprec_t * rx_frame, mandata_pon_type_t mandata_pon);
+static int json_cli_cmd(tb_pkt_deprec_t *);
+
+static int json_str_append_and_out(char *, char *, json_string_print_t, tb_pkt_deprec_t *);
+
+// mac_address mgmt_mac_addr = { .u8 = { 0x08, 0x00, 0x27, 0x63, 0xe8, 0x6e } };
+mac_address mgmt_mac_addr = { .u8 = { 0x84, 0x38, 0x35, 0x4e, 0x9b, 0xb2 } };
+
+void mgmt_mac_addr_set(const mac_address *new_mgmt_mac_addr) {
+    tb_mac_address_str_t  old;
+
+    assert(new_mgmt_mac_addr);
+
+    tb_mac_address_to_str(mgmt_mac_addr.u8, old);
+
+    if (0 != memcmp(mgmt_mac_addr.u8, new_mgmt_mac_addr->u8, sizeof(mgmt_mac_addr))) {
+        tb_mac_address_str_t  new;
+
+        tb_mac_address_to_str(new_mgmt_mac_addr->u8, new);
+
+        TB_TRACE("updating mgmt_mac_addr   %s -> %s", old, new);
+
+        memcpy(mgmt_mac_addr.u8, new_mgmt_mac_addr->u8, sizeof(mgmt_mac_addr));
+    } else {
+        // TB_TRACE("mgmt_mac_addr %s (unchanged)", old);
+    }
+}
+
+void mgmt_mac_addr_get(void *mgmt_mac_addr_dest) {
+    assert(mgmt_mac_addr_dest);
+    memcpy(mgmt_mac_addr_dest, mgmt_mac_addr.u8, sizeof(mgmt_mac_addr));
+}
+
+/**
+ *  @brief Forward an OAM Request to the designated MAC Address
+ *
+ * @param rx_frame   Pointer to OAM message to be forwarded
+ * @param dst_mac    Pointer to Destination MAC Address
+ * @param src_mac    Pointer to Source MAC Address
+ * @param oam_start  Pointer to Protocol Subtype (0x03 for OAM) in frame
+ * @param onu_vid    ONU VID Value
+ *
+ * @return tb_rc
+ */
+static
+tb_rc cli_forward_oam(tb_pkt_deprec_t * rx_frame, mac_address *dst_mac,
+                      mac_address *src_mac, const uint8_t *oam_start, uint16_t onu_vid)
+{
+    tb_rc rc = TB_RC_OK;
+
+    unsigned int payload_length = ((unsigned int)rx_frame->num_bytes) - (oam_start - &rx_frame->preamble_start[0]);
+    unsigned int frame_length = 0;
+
+    /* Set destination MAC to EOAM multicast mac */
+    memcpy(&rx_frame->preamble_start[8], &multicast_da_oam, sizeof(mac_address));
+
+    /* Set source MAC to OLT MAC address */
+    memcpy(&rx_frame->preamble_start[14], &tbg.mac_1_address, sizeof(mac_address));
+
+    /* Set the type and copy in the payload */
+    tb_pack_u16(&rx_frame->preamble_start[20], 0x8809);
+
+    /* Zero out CRC on frame just to make sure that it is not be reused */
+    memset(&rx_frame->preamble_start[rx_frame->num_bytes - 4], 0, 4);
+
+    /* Copy in the frame */
+    memcpy(&rx_frame->preamble_start[22], oam_start, payload_length);
+
+    /* NEW Frame Length */
+    frame_length = 6    /* dest  */
+        + 6             /* source */
+        + 2             /* type */
+        + payload_length;
+
+    TB_TRACE("tx length %d (w/o preamble)", frame_length);
+    rx_frame->num_bytes = frame_length;
+
+    rc = oam_olt_send_oam_to_onu(rx_frame->preamble_start + 8, frame_length,
+                                 src_mac, dst_mac, OLT_OAM_ORIGIN_HOST, onu_vid);
+    return rc;
+}
+
+
+tb_rc cli_handle_rx_frame(tb_pkt_deprec_t * rx_frame)
+{
+    tb_rc rc = TB_RC_OK;
+    unsigned int jsonType = 0;
+    const uint8_t  *payload_start = &rx_frame->preamble_start[8]; // real payload starts after 8-byte preamble
+    const uint8_t  *ethtype_start = payload_start + 2*sizeof(mac_address);
+    const uint8_t  *json_start;
+    uint16_t vid = 0;
+    unsigned short  ethType       = (ethtype_start[0] << 8) | ethtype_start[1];
+
+    mac_address  dest_addr;
+    memcpy(dest_addr.u8, payload_start, sizeof(mac_address));
+
+    mac_address  remote_addr;
+    memcpy(remote_addr.u8, payload_start+sizeof(mac_address), sizeof(mac_address));
+    mgmt_mac_addr_set((const mac_address *)(payload_start+sizeof(mac_address)));
+
+    tb_mac_address_str_t  remote_addr_str;
+    tb_mac_address_to_str(remote_addr.u8, remote_addr_str);
+
+    tb_dbug_hexdump_one_line(TB_DBUG_LVL_DEBUG, __FUNCTION__, __LINE__, rx_frame->preamble_start, 0, rx_frame->num_bytes+8, COLOR_RED "Frame:   " COLOR_OFF , "<---");
+
+    TB_DEBUG("payload_start %p  remote %s   ethtype_start %p   ethtype %04x  num_bytes %u   rx_que %u   tx_que %u   data %08lx", payload_start, remote_addr_str, ethtype_start, ethType, rx_frame->num_bytes, rx_frame->rx_que, rx_frame->tx_que, (uint32_t) rx_frame->data);
+
+    while ((0x88a8 == ethType) || (0x8100 == ethType)) {
+        vid = ((ethtype_start[2] << 8) | ethtype_start[3]) & 0xfff;
+        TB_TRACE("skipping %c-tag, value %04d (0x%03x), ethtype_start %p -> %p",
+                 (0x88a8 == ethType) ? 'S' : 'C',
+                 vid, vid,
+                 ethtype_start,
+                 ethtype_start+4);
+
+        ethtype_start += 4;
+        ethType = (ethtype_start[0] << 8) | ethtype_start[1];
+    }
+    json_start = ethtype_start + 2;
+    if (ethType != 0x9001) {
+        TB_WARNING("FRAME ETHERTYPE NOT 0x9001");
+        TB_ERROR("ethtype  0x%04x (actual) vs. 0x9001 (expected)", ethType);
+        tb_dbug_hexdump_one_line(TB_DBUG_LVL_ERROR, __FUNCTION__, __LINE__,
+                                     rx_frame->preamble_start,
+                                     0,
+                                     rx_frame->num_bytes+8,
+                                     COLOR_RED "Frame:   ", "<---" COLOR_OFF );
+        return 0;
+    }
+
+    jsonType = ((json_start[0] << 24) |
+                (json_start[1] << 16) |
+                (json_start[2] <<  8) |
+                (json_start[3] <<  0));
+
+    switch (jsonType) {
+        case COPY_TYPE: {
+            uint32 length = ((unsigned int)rx_frame->num_bytes) - (json_start - &rx_frame->preamble_start[0]);
+            process_copy(json_start+4, length);
+            break;
+        } // case COPY_TYPE
+
+        case DNLD_TYPE: {
+            uint32 length = ((unsigned int)rx_frame->num_bytes) - (json_start - &rx_frame->preamble_start[0]);
+            process_dnld(json_start+4, length);
+            break;
+        } // case DNLD_TYPE
+
+        case JSON_TYPE:
+            process_json(rx_frame);
+            break;
+
+            // case 0x030050fe:        /* 03:OAM 0050:FLAGS fe:OAMPDU */
+        default: {
+            uint8_t  subtype = json_start[0];
+
+            switch (subtype) {
+
+                case slow_protocol_subtype_oam: {
+                    uint16_t flags_expected = oam_flag_loc_stab | oam_flag_rem_stab; // 0x50;
+                    uint16_t flags_actual   = tb_unpack_u16(json_start+1);
+
+                    if (flags_expected != flags_actual) {
+                        TB_WARNING("unexpected flags  0x%04x actual vs. 0x%04x expected",
+                            flags_actual, flags_expected);
+                        rc = TB_RC_REMOTE_PEER_RESP;
+                    } else {
+                        uint8_t        opcode               = json_start[3];
+
+                        switch (opcode) {
+                            case oam_pdu_code_organization_specific: {
+
+                                /* If the destination address for the OAM PDU was the OLT's
+                                 * ethernet port, then invoke the local OAM handling code. */
+                                if ((!memcmp(dest_addr.u8, tbg.mac_0_address.u8, sizeof(mac_address))) &&
+                                    (vid == 0))
+                                {
+                                    uint32 length = ((unsigned int)rx_frame->num_bytes) - (json_start - &rx_frame->preamble_start[0]);
+
+                                    if (0 == memcmp(json_start+4, dpoe_oui, 3)) {
+                                        TB_TRACE("dispatching to DPoE organization-specific handler");
+                                        rc = oam_hdl_org_spec_dpoe(&remote_addr, json_start+7, length-7);
+                                    } else if (0 == memcmp(json_start+4, tibit_oam_oui, 3)) {
+                                        TB_TRACE("dispatching to Tibit organization-specific handler");
+                                        rc = oam_hdl_org_spec_tibit(&remote_addr, json_start+7, length-7);
+                                    } else {
+                                        uint32         oui                  = tb_unpack_u24(json_start+4);
+                                        TB_ERROR("unknown organization-specific OUI %06x", oui);
+                                        rc = TB_RC_REMOTE_PEER_RESP;
+                                    }
+
+                                } else if (olt_device_p()) {
+                                    /* Forward the OAM request */
+                                    if (vid != 0) {
+                                        /* Constructing the ONU MAC address from the VLAN value. For the board MAC
+                                         * address, all Tibit MAC addresses use the EPON identifier */
+                                        dest_addr.u8[3] = (unsigned char)(MANDATA_PON_TYPE_10G_EPON_ONU << 4)
+                                            | TB_IFC_TYPE_ONU;
+                                        dest_addr.u8[4] = (vid - VOLTHA_ONU_BASE_VLAN);
+                                    }
+                                    dest_addr.u8[0] = 0x00;
+                                    dest_addr.u8[1] = 0x25;
+                                    dest_addr.u8[2] = 0xdc;
+                                    dest_addr.u8[3] = 0xd9;
+
+                                    dest_addr.u8[5] = 0x10;
+
+                                    rc = cli_forward_oam(rx_frame, &dest_addr, &remote_addr, json_start, vid);
+                                } else {
+                                    TB_ERROR("Can only forward OAM PDUs from an OLT");
+                                    rc = TB_RC_REMOTE_PEER_RESP;
+                                }
+
+                                break;
+                            } // case 0xfe
+
+                            default:
+                                TB_ERROR("unknown opcode 0x%x", opcode);
+                                rc = TB_RC_REMOTE_PEER_RESP;
+                                break;
+                        } // switch (opcode)
+                    } // else
+
+                    break;
+                } // case slow_protocol_subtype_oam
+
+                default:
+                    TB_ERROR("unknown subtype 0x%02x", subtype);
+                    rc = TB_RC_REMOTE_PEER_RESP;
+                    break;
+            } // switch (subtype)
+
+            // uint32 length = ((unsigned int)rx_frame->num_bytes) - (json_start - &rx_frame->preamble_start[0]);
+            TB_TRACE("rx_frame->num_bytes %u  json_offset %u", rx_frame->num_bytes, (json_start - &rx_frame->preamble_start[0]));
+
+            tb_dbug_hexdump_one_line(TB_DBUG_LVL_TRACE, __FUNCTION__, __LINE__,
+                                     rx_frame->preamble_start,
+                                     0,
+                                     rx_frame->num_bytes+8,
+                                     "Frame:   ", "<---");
+
+            const uint8_t *dpoe_org_spec_start = json_start;
+            uint32        dpoe_org_spec_length = ((unsigned int)rx_frame->num_bytes) - (json_start - &rx_frame->preamble_start[0]);
+
+            tb_dbug_hexdump_one_line(TB_DBUG_LVL_TRACE, __FUNCTION__, __LINE__, dpoe_org_spec_start, 0, dpoe_org_spec_length, "orgspec: ", "<---");
+            break;
+        } // default
+    } // switch (jsonType)
+
+    return rc;
+}
+
+static int dump(const char *js, jsmntok_t * t, size_t count, int indent)
+{
+    int i, j, k;
+    static int found_operation = 0;
+    static int found_location = 0;
+    static int found_value = 0;
+    static int found_llid = 0;
+    static int found_macblock = 0;
+    static int found_itype = 0;
+    static int found_iinst = 0;
+    static int found_mac = 0;
+    static int found_cir = 0;
+    static int found_eir = 0;
+    static int found_swr = 0;
+    static int found_cvid = 0;
+    static int found_svid = 0;
+    static int found_cmd = 0;
+    static int found_code = 0;
+    static int found_tpid = 0;
+    static int found_vid = 0;
+    static int found_mode = 0;
+    static int found_tag_mode = 0;
+
+    if (count == 0) {
+        return 0;
+    }
+    if (t->type == JSMN_PRIMITIVE) {
+        TB_TRACE("PRIMITIVE: ");
+        TB_TRACE("%.*s", t->end - t->start, js + t->start);
+        return 1;
+    } else if (t->type == JSMN_STRING) {
+        TB_INFO("STRING: ");
+        TB_INFO("'%.*s'", t->end - t->start, js + t->start);
+        /*--- "operation" command ------------------------------------------*/
+        if (found_operation == 1) {
+            TB_INFO(" ACTION: storing 'operation' string");
+            if (strncmp("code", js + t->start, t->end - t->start) == 0) {
+                TB_TRACE("skipping code!");
+            } else {
+                memset(operation, 0, SIZE_OF_OPERATION);
+                strncpy(operation, js + t->start, t->end - t->start);
+            }
+            found_operation = 0;
+        }
+        if (strncmp("operation", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'operation'");
+            found_operation = 1;
+        }
+        /*--- "location" command -------------------------------------------*/
+        if (found_location == 1) {
+            TB_INFO(" ACTION: storing 'location'");
+            memset(location, 0, SIZE_OF_ADDRESS);
+            strncpy(location, js + t->start, t->end - t->start);
+            found_location = 0;
+        }
+        if (strncmp("address", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'location'");
+            found_location = 1;
+        }
+        /*--- "value" ------------------------------------------------------*/
+        if (found_value == 1) {
+            TB_INFO(" ACTION: storing 'value'");
+            memset(value, 0, SIZE_OF_VALUE);
+            strncpy(value, js + t->start, t->end - t->start);
+            found_value = 0;
+        }
+        if (strncmp("value", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'value'");
+            found_value = 1;
+        }
+        /*--- "llid" -------------------------------------------------------*/
+        if (found_llid == 1) {
+            TB_INFO(" ACTION: storing 'llid'");
+            memset(llid, 0, SIZE_OF_LLID);
+            strncpy(llid, js + t->start, t->end - t->start);
+            found_llid = 0;
+        }
+        if (strncmp("llid", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'llid'");
+            found_llid = 1;
+        }
+        /*--- "macblock" ---------------------------------------------------*/
+        if (found_macblock == 1) {
+            TB_INFO(" ACTION: storing 'macblock'");
+            memset(macblock, 0, SIZE_OF_MACBLOCK);
+            strncpy(macblock, js + t->start, t->end - t->start);
+            found_macblock = 0;
+        }
+        if (strncmp("macblock", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'macblock'");
+            found_macblock = 1;
+        }
+        /*--- "itype" ---------------------------------------------------*/
+        if (found_itype == 1) {
+            TB_INFO(" ACTION: storing 'itype'");
+            strncpy(itype, js + t->start, t->end - t->start);
+            found_itype = 0;
+        }
+        if (strncmp("itype", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'itype'");
+            found_itype = 1;
+        }
+        /*--- "iinst" ---------------------------------------------------*/
+        if (found_iinst == 1) {
+            TB_INFO(" ACTION: storing 'iinst'");
+            strncpy(iinst, js + t->start, t->end - t->start);
+            found_iinst = 0;
+        }
+        if (strncmp("iinst", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'iinst'");
+            found_iinst = 1;
+        }
+        /*--- "swr" ---------------------------------------------------*/
+        if (found_swr == 1) {
+            TB_INFO(" ACTION: storing 'swr'");
+            strncpy(swr, js + t->start, t->end - t->start);
+            found_swr = 0;
+        }
+        if (strncmp("swr", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'swr'");
+            found_swr = 1;
+        }
+        /*--- "mac" --------------------------------------------------------*/
+        if (found_mac == 1) {
+            TB_INFO(" ACTION: storing 'mac'");
+            strncpy(mac, js + t->start, t->end - t->start);
+
+            if (sizeof(mac_addr) != tb_str_to_buf(mac_addr.u8, mac, sizeof(mac_addr))) {
+                TB_ERROR("failed to parse macid `%s'", mac);
+            }
+
+            found_mac = 0;
+        }
+        if (strncmp("mac", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'mac'");
+            found_mac = 1;
+        }
+        /*--- "macid" ------------------------------------------------------*/
+        if (found_mac == 1) {
+            TB_INFO(" ACTION: storing 'macid'");
+            strncpy(mac, js + t->start, t->end - t->start);
+
+            if (sizeof(mac_addr) != tb_str_to_buf(mac_addr.u8, mac, sizeof(mac_addr))) {
+                TB_ERROR("failed to parse macid `%s'", mac);
+            }
+
+            found_mac = 0;
+        }
+        if (strncmp("macid", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'macid'");
+            found_mac = 1;
+        }
+        /*--- "cir" ---------------------------------------------------*/
+        if (found_cir == 1) {
+            TB_INFO(" ACTION: storing 'cir'");
+            strncpy(cir, js + t->start, t->end - t->start);
+            found_cir = 0;
+        }
+        if (strncmp("cir", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'cir'");
+            found_cir = 1;
+        }
+        /*--- "eir" ---------------------------------------------------*/
+        if (found_eir == 1) {
+            TB_INFO(" ACTION: storing 'eir'");
+            strncpy(eir, js + t->start, t->end - t->start);
+            found_eir = 0;
+        }
+        if (strncmp("eir", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'eir'");
+            found_eir = 1;
+        }
+        /*--- "svid" ---------------------------------------------------*/
+        if (found_svid == 1) {
+            TB_INFO(" ACTION: storing 'svid'");
+            strncpy(svid, js + t->start, t->end - t->start);
+            found_svid = 0;
+        }
+        if (strncmp("svid", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'svid'");
+            found_svid = 1;
+        }
+        /*--- "cvid" ---------------------------------------------------*/
+        if (found_cvid == 1) {
+            TB_INFO(" ACTION: storing 'cvid'");
+            strncpy(cvid, js + t->start, t->end - t->start);
+            found_cvid = 0;
+        }
+        if (strncmp("cvid", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'cvid'");
+            found_cvid = 1;
+        }
+        /*--- "cmd" --------------------------------------------------------*/
+        if (found_cmd == 1) {
+            TB_INFO(" ACTION: storing 'cmd'");
+            strncpy(cmd, js + t->start, t->end - t->start);
+            found_cmd = 0;
+        }
+        if (strncmp("cmd", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'cmd'");
+            found_cmd = 1;
+        }
+        /*--- "code" -------------------------------------------------------*/
+        if (found_code == 1) {
+            TB_INFO(" ACTION: storing 'code'");
+            memset(code, 0, sizeof(CODE_STR_LEN));
+            strncpy(code, js + t->start, t->end - t->start);
+            found_code = 0;
+        }
+        if (strncmp("code", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'code'");
+            found_code = 1;
+        }
+        /*--- "tpid" -------------------------------------------------------*/
+        if (found_tpid == 1) {
+            TB_INFO(" ACTION: storing 'tpid'");
+            memset(tpid, 0, sizeof(TPID_STR_LEN));
+            strncpy(tpid, js + t->start, t->end - t->start);
+            found_tpid = 0;
+        }
+        if (strncmp("tpid", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'tpid'");
+            found_tpid = 1;
+        }
+        /*--- "vid" --------------------------------------------------------*/
+        if (found_vid == 1) {
+            TB_INFO(" ACTION: storing 'vid'");
+            memset(vid, 0, sizeof(VID_STR_LEN));
+            strncpy(vid, js + t->start, t->end - t->start);
+            found_vid = 0;
+        }
+        if (strncmp("vid", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'vid'");
+            found_vid = 1;
+        }
+        /*--- "mode" --------------------------------------------------------*/
+        if (found_mode == 1) {
+            TB_INFO(" ACTION: storing 'mode'");
+            memset(mode, 0, sizeof(MODE_STR_LEN));
+            strncpy(mode, js + t->start, t->end - t->start);
+            found_mode = 0;
+        }
+        if (strncmp("mode", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'mode'");
+            found_mode = 1;
+        }
+        /*--- "mode" --------------------------------------------------------*/
+        if (found_tag_mode == 1) {
+            TB_INFO(" ACTION: storing 'tag_mode'");
+            memset(tag_mode, 0, sizeof(TAG_MODE_STR_LEN));
+            strncpy(tag_mode, js + t->start, t->end - t->start);
+            found_tag_mode = 0;
+        }
+        if (strncmp("tag_mode", js + t->start, t->end - t->start) == 0) {
+            TB_INFO(" ACTION: found 'tag_mode'");
+            found_tag_mode = 1;
+        }
+        return 1;
+    } else if (t->type == JSMN_OBJECT) {
+        TB_INFO("OBJECT: ");
+        TB_INFO("\n");
+        j = 0;
+        for (i = 0; i < t->size; i++) {
+            for (k = 0; k < indent; k++)
+                TB_INFO("  ");
+            /* tb_printf("---  dump one --- [j=%d] [count=%d, count - j = %d]\n", j, count, count-j); */
+            j += dump(js, t + 1 + j, count - j, indent + 1);
+            TB_INFO(": ");
+            if ((count - j - 1) > 0) {
+                /* tb_printf("---  dump two --- [j=%d] [count=%d, count - j = %d]\n", j, count, count-j); */
+                j += dump(js, t + 1 + j, count - j, indent + 1);
+            }
+            TB_INFO("\n");
+        }
+        return j + 1;
+    } else if (t->type == JSMN_ARRAY) {
+        TB_INFO("ARRAY: ");
+        j = 0;
+        TB_INFO("\n");
+        for (i = 0; i < t->size; i++) {
+            for (k = 0; k < indent - 1; k++)
+                TB_INFO("  ");
+            TB_INFO("   - ");
+            j += dump(js, t + 1 + j, count - j, indent + 1);
+            TB_INFO("\n");
+        }
+        return j + 1;
+    }
+    return 0;
+}
+
+static int json_version(tb_pkt_deprec_t * rx_frame)
+{
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    brdg_mem_t brdg_memory;
+    tb_mac_address_str_t mac_str;
+    brdg_return_t rc;
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    sprintf(tmp_string, "{\"operation\": \"version\", \"success\": true, \"results\": {");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    /* get bridge memory values */
+    brdg_mem_t_init(&brdg_memory);
+    brdg_memory.addr = 0x10000000;
+    brdg_memory.num = 3;
+    rc = brdg_mem_read(&brdg_memory);
+
+    if (rc != BRDG_RET_OK) {
+        json_error(rx_frame, rc);
+    }
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"manufacturer\": \"%08x\",", brdg_memory.data[0]);
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    switch (tbg.PON) {
+        case MANDATA_PON_TYPE_10G_EPON_ONU:
+            sprintf(tmp_string, "\"device\": \"10G EPON ONU\",");
+            break;
+        case MANDATA_PON_TYPE_10G_EPON_OLT:
+            sprintf(tmp_string, "\"device\": \"10G EPON OLT\",");
+            break;
+        case MANDATA_PON_TYPE_10G_GPON_ONU:
+            sprintf(tmp_string, "\"device\": \"10G GPON ONT\",");
+            break;
+        case MANDATA_PON_TYPE_10G_GPON_OLT:
+            sprintf(tmp_string, "\"device\": \"10G GPON OLT\",");
+            break;
+        case MANDATA_PON_TYPE_1G_P2P:
+        case MANDATA_PON_TYPE_10G_P2P:
+            sprintf(tmp_string, "\"device\": \"10G/1G LAN\",");
+            break;
+        case MANDATA_PON_TYPE_1G_EPON_ONU:
+        case MANDATA_PON_TYPE_1G_GPON_ONU:
+        case MANDATA_PON_TYPE_1G_GPON_OLT:
+        case MANDATA_PON_TYPE_1G_EPON_OLT:
+            sprintf(tmp_string, "\"device\": \"1G PON DEVICE\",");
+            break;
+        default:
+        case MANDATA_PON_TYPE_UNK:
+            sprintf(tmp_string, "\"device\": \"UNK\",");
+            break;
+    }
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"datecode\": \"%08x\",", brdg_memory.data[2]);
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"firmware\": \"%02d:%02d:%02d\",", __VERSION_MAJOR__, __VERSION_MINOR__,
+            __VERSION_REVISION__);
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"modelversion\": \"%s\",", "1.0");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"macid\": \"%s\"", tb_mac_address_to_str(tbg.mac_0_address.u8, mac_str));
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}, ");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"error\": null");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+    return 0;
+}
+
+static int json_interfaces(tb_pkt_deprec_t * rx_frame)
+{
+    int i;
+    uint8_t max_count = 5;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    tb_ifc_key_t olt_ifc_keys[JSON_MAX_INTERFACES];
+    tb_ifc_key_t onu_ifc_keys[JSON_MAX_INTERFACES];
+    tb_ifc_key_t eth_ifc_keys[JSON_MAX_INTERFACES];
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"interfaces\", \"success\": true, \"results\":[");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    if (onu_device_p()) {
+        onu_fsm_report_all_ifc_keys(&max_count, onu_ifc_keys);
+        if (max_count < JSON_MAX_INTERFACES) {
+            for (i = 0; i < max_count; i++) {
+                memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                sprintf(tmp_string, "{\"iinst\": \"%d\", \"itype\": \"onu\"}, ",
+                        onu_ifc_keys[i].inst);
+                json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+            }
+        } else {
+            TB_TRACE("E:Num ifcs > size of table (%s:%d)", __FUNCTION__, __LINE__);
+        }
+    }
+
+    if (olt_device_p()) {
+        olt_fsm_report_all_ifc_keys(&max_count, olt_ifc_keys);
+        if (max_count < JSON_MAX_INTERFACES) {
+            for (i = 0; i < max_count; i++) {
+                memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                sprintf(tmp_string, "{\"iinst\": \"%d\", \"itype\": \"olt\"}, ",
+                        olt_ifc_keys[i].inst);
+                json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+            }
+        } else {
+            TB_TRACE("E:Num ifcs > size of table (%s:%d)", __FUNCTION__, __LINE__);
+        }
+    }
+
+    eth_fsm_report_all_ifc_keys(&max_count, eth_ifc_keys);
+    if (max_count < JSON_MAX_INTERFACES) {
+        for (i = 0; i < max_count; i++) {
+            memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+            sprintf(tmp_string, "{\"iinst\": \"%d\", \"itype\": \"eth\"}", eth_ifc_keys[i].inst);
+            json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+        }
+    } else {
+        TB_TRACE("E:Num ifcs > size of table (%s:%d)", __FUNCTION__, __LINE__);
+    }
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "],\"error\":null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return 0;
+}                               /* json_interfaces */
+
+#define MAX_REGISTERED_LINKS 16 /* for now... */
+static int json_links(tb_pkt_deprec_t * rx_frame, UNUSED_ARG char *itype, UNUSED_ARG tb_ifc_inst_t iinst)
+{
+    int i;
+    tb_mac_address_str_t mac_str = "";
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    mac_address all_zeros_mac = {.u8 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
+    int num_links = 0;
+
+    mac_address registered_mac_addresses[MAX_REGISTERED_LINKS];
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    num_links = lsm_report_all_links_mgmt(registered_mac_addresses);
+
+    if (num_links >= MAX_REGISTERED_LINKS) {
+        TB_ERROR("Out of bounds error, more links than memory allocated");
+    } else if (num_links < 0) {
+        /* error condition */
+        TB_TRACE("I: (%s:%d)", __FUNCTION__, __LINE__);
+    }
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"links\", ");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    if (num_links) {
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        sprintf(tmp_string, "\"success\": true, \"results\":[");
+        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+        for (i = 0; i < num_links; i++) {
+            memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+            tb_mac_address_to_str(registered_mac_addresses[i].u8, mac_str);
+            if (i + 1 == num_links) {
+                sprintf(tmp_string, "{\"macid\": \"%s\"}", mac_str);
+            } else {
+                sprintf(tmp_string, "{\"macid\": \"%s\"},", mac_str);
+            }
+            json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+        }
+    } else {
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        sprintf(tmp_string, "\"success\": true, \"results\":[");
+        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        tb_mac_address_to_str(all_zeros_mac.u8, mac_str);
+        /* sprintf(tmp_string, "{\"macid\": \"%s\"}", mac_str); */
+        /* json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame); */
+    }
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return 0;
+}                               /* json_links */
+
+static int json_register_read(tb_pkt_deprec_t * rx_frame, unsigned int address)
+{
+    brdg_mem_t brdg_memory;
+    brdg_return_t rc = BRDG_RET_OK;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"register_read\", \"success\": true, \"results\": {");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+
+    brdg_mem_t_init(&brdg_memory);
+    brdg_memory.addr = address;
+    brdg_memory.num = 1;
+    rc = brdg_mem_read(&brdg_memory);
+
+    sprintf(tmp_string, "\"value\": \"%08x\"", brdg_memory.data[0]);
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}, ");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"error\": null");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+static int json_register_write(tb_pkt_deprec_t * rx_frame, unsigned int address, unsigned int value)
+{
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    brdg_mem_t brdg_memory;
+    brdg_return_t rc = BRDG_RET_OK;
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    brdg_mem_t_init(&brdg_memory);
+    brdg_memory.addr = address;
+    brdg_memory.num = 1;
+    brdg_memory.data[0] = value;
+    rc = brdg_mem_write(&brdg_memory);
+
+    if (rc == BRDG_RET_OK) {
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        sprintf(tmp_string,
+                "{\"operation\": \"register_write\", \"success\": true, \"error\": null}");
+        json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+    } else {
+        json_error(rx_frame, rc);
+    }
+
+    return rc;
+
+}                               /* json_register_write */
+
+static int json_stats(tb_pkt_deprec_t * rx_frame, unsigned int lidx, brdg_mac_block_t mac_block)
+{
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    unsigned long long int wide_total = 0;
+    brdg_return_t rc = BRDG_RET_OK;
+    brdg_dpram_t output;
+    brdg_dpram_t *p_out;
+    unsigned int s;
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    p_out = &output;
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"stats\", \"success\": true, \"results\":{");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    for (s = 0; s < 31; s++) {
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        p_out->num = 1;
+        if (lidx == 256) {
+            rc = (mac_block == MB0) ? brdg_dpram_read(SLCT_MSTAT_RDCLR_0, (s << 5) | 31,
+                                                      p_out) : brdg_dpram_read(SLCT_MSTAT_RDCLR_1,
+                                                                               (s << 5) | 31,
+                                                                               p_out);
+        } else {
+            rc = (mac_block == MB0) ? brdg_dpram_read(SLCT_MSTAT_RDCLR_0, (lidx << 5) | s,
+                                                      p_out) : brdg_dpram_read(SLCT_MSTAT_RDCLR_1,
+                                                                               (lidx << 5) | s,
+                                                                               p_out);
+        }
+        if (rc == BRDG_RET_OK) {
+            sprintf(tmp_string, "\"%s\":\"%u\", ", brdg_stat_name_lower[s], p_out->data[0]);
+        }
+        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+    }
+
+    for (s = 0; s < 7; s++) {
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        p_out->num = 2;
+        if (lidx == 256) {
+            rc = (mac_block == MB0) ? brdg_dpram_read(SLCT_MWIDE_RDCLR_0, (s << 3) | 7,
+                                                      p_out) : brdg_dpram_read(SLCT_MWIDE_RDCLR_1,
+                                                                               (s << 3) | 7, p_out);
+        } else {
+            rc = (mac_block == MB0) ? brdg_dpram_read(SLCT_MWIDE_RDCLR_0, (lidx << 3) | s,
+                                                      p_out) : brdg_dpram_read(SLCT_MWIDE_RDCLR_1,
+                                                                               (lidx << 3) | s,
+                                                                               p_out);
+        }
+        if (rc == BRDG_RET_OK) {
+            wide_total = p_out->data[1];
+            wide_total <<= 32ULL;
+            wide_total += p_out->data[0];
+            if (s != 6) {       /* ! last one */
+                sprintf(tmp_string, "\"%s\":\"%llu\", ", brdg_stat_total_lower[s], wide_total);
+            } else {
+                sprintf(tmp_string, "\"%s\":\"%llu\"", brdg_stat_total_lower[s], wide_total);
+            }
+        }
+        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+    }
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}, ");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"error\": null");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+static int json_error(tb_pkt_deprec_t * rx_frame, brdg_return_t brdg_return_code)
+{
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"%s\", \"success\": false, \"results\": {}, ", operation);
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    switch (brdg_return_code) {
+    case BRDG_RET_INPUT_INVALID:
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        sprintf(tmp_string, "\"error\": {\"code\": 2, \"message\": \"Missing parameters\"");
+        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+        break;
+    default:
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        sprintf(tmp_string, "\"error\": {\"code\": 5, \"message\": \"Unknown error\"");
+        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+        break;
+    }
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return 0;
+}
+
+static int json_str_append_and_out(char *global_json_string, char *tmp_string,
+                                   json_string_print_t output, tb_pkt_deprec_t * rx_frame)
+{
+    uint i;
+    static int offset = 0;
+    mac_address tmp_mac;
+
+    if (output != RESET) {
+        TB_TRACE("jstr: @pos[%d] + %d chars", offset, (int)strlen(tmp_string));
+        strncpy(global_json_string + offset, tmp_string, strlen(tmp_string));
+        offset += strlen(tmp_string);
+    }
+
+    switch (output) {
+    case RESET:
+        offset = 0;
+        break;
+
+    case APPEND_AND_FLUSH:
+        offset = 0;
+        TB_TRACE("%s", global_json_string);
+        break;
+
+    case APPEND_AND_FLUSH_CR:
+        if (command_line_json) {
+            tb_printf("%s\n", global_json_string);
+            command_line_json = false;
+        } else {
+            TB_TRACE("%s", global_json_string);
+        }
+        /* store src address in tmp */
+        memcpy(tmp_mac.u8, &rx_frame->preamble_start[14], sizeof(mac_address));
+        /* make src my mac */
+        memcpy(&rx_frame->preamble_start[14], tbg.mac_0_address.u8, sizeof(mac_address));
+        /* make tmp src new dst */
+        memcpy(&rx_frame->preamble_start[8], tmp_mac.u8, sizeof(mac_address));
+        if (tbg.mgmt_vlan != MGMT_VLAN_DISABLED) {
+            /* VLAN HEADER: */
+            rx_frame->preamble_start[20] = tbg.outer_tpid >> 8;
+            rx_frame->preamble_start[21] = tbg.outer_tpid & 0xff;
+            rx_frame->preamble_start[22] = (MGMT_VLAN_PRIORITY << 5) | (tbg.mgmt_vlan >> 8);
+            rx_frame->preamble_start[23] = tbg.mgmt_vlan & 0xff;
+            rx_frame->preamble_start[24] = 0x90;
+            rx_frame->preamble_start[25] = 0x01;
+            rx_frame->preamble_start[26] = 0x6a;   /* j */
+            rx_frame->preamble_start[27] = 0x73;   /* s */
+            rx_frame->preamble_start[28] = 0x6f;   /* o */
+            rx_frame->preamble_start[29] = 0x6e;   /* n */
+            rx_frame->preamble_start[30] = 0x20;   /* 'space' */
+            /* FIX: Magic numbers +4 for VLAN, START_OF_JSON_VLAN header, offset = payload, 4 for CRC */
+            rx_frame->num_bytes = 4 + START_OF_JSON_VLAN + offset;
+            TB_TRACE("num_bytes %d", rx_frame->num_bytes);
+            memcpy(&rx_frame->preamble_start[START_OF_JSON_VLAN], global_json_string, rx_frame->num_bytes);
+        } else {
+            /* FIX: Magic numbers START_OF_JSON_UNTAGGED header, offset = payload, 4 for CRC */
+            rx_frame->num_bytes = START_OF_JSON_UNTAGGED + offset + 4;
+            memcpy(&rx_frame->preamble_start[START_OF_JSON_UNTAGGED], global_json_string, rx_frame->num_bytes);
+        }
+        for (i = 0; i < rx_frame->num_bytes; ++i) {
+            uint16_t dword_idx = i / 4;
+            uint8_t byte_shift = (3 - (i % 4)) << 3;    // 0->24, 1->16, 2->8, 3->0
+
+            //   i   3-(i%4)   byte_shift
+            // --------------------------
+            //   0      3          24
+            //   1      2          16
+            //   2      1           8
+            //   3      0           0
+            //   4      3          24
+            //   5      2          16
+            //   6      1           8
+            //   ⋮      ⋮           ⋮
+            if (0 == (i % 4)) {
+                rx_frame->data[dword_idx] = 0;
+            }
+            rx_frame->data[dword_idx] |= (rx_frame->preamble_start[i] << byte_shift);
+        }
+
+        rx_frame->tx_modifier = BRDG_MODIFIER_FLAG_APPLY_CRC;
+
+        brdg_que_write(7, BRDG_MODIFIER_FLAG_APPLY_CRC, rx_frame);
+
+        offset = 0;
+        break;
+    case APPEND:
+    default:
+        /* do nothing */
+        break;
+    }
+
+    return 0;
+}
+
+static tb_rc json_fec_set(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key, bool fec_enabled)
+{
+    tb_rc rc = TB_RC_OK;
+
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string,
+            "{\"operation\": \"fec_set\", \"success\": true, \"results\": [], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    olt_fsm_fec_enable_set(ifc_key, fec_enabled, fec_enabled);
+
+    return rc;
+}
+
+static tb_rc json_fec_get(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key)
+{
+    tb_rc rc = TB_RC_OK;
+    bool fec_tx_enable = false;
+    bool fec_rx_enable = false;
+
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"fec_get\", \"success\": true, \"results\": ");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    rc = olt_fsm_fec_enable_get(ifc_key, &fec_tx_enable, &fec_rx_enable);
+
+    if (fec_tx_enable == true) {
+        sprintf(tmp_string, "{\"mode\": \"enabled\"}");
+    } else {
+        sprintf(tmp_string, "{\"mode\": \"disabled\"}");
+    }
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, ", \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+static tb_rc json_tag_mode_set(tb_pkt_deprec_t * rx_frame, char * tag_mode)
+{
+    tb_rc rc = TB_RC_OK;
+
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string,
+            "{\"operation\": \"tag_mode_set\", \"success\": true, \"results\": [], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    if (strncmp(tag_mode, "SC", 3) == 0) {
+        rc = hwsys_manufacturing_CTAG_CTAG_write(false);
+    } else {
+        rc = hwsys_manufacturing_CTAG_CTAG_write(true);
+    }
+
+    return rc;
+}
+
+static tb_rc json_tag_mode_get(tb_pkt_deprec_t * rx_frame)
+{
+    tb_rc rc = TB_RC_OK;
+
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"tag_mode_get\", \"success\": true, \"results\": ");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+
+    if (tbg.outer_tpid == 0x8100) {
+        sprintf(tmp_string, "{\"tag_mode\": \"CC\"}");
+    } else {
+        sprintf(tmp_string, "{\"tag_mode\": \"SC\"}");
+    }
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, ", \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+static tb_rc json_sla_set(tb_pkt_deprec_t * rx_frame, lsm_link_key_t * link_key,
+                          lsm_link_sla_spec_t * sla_spec)
+{
+    tb_rc rc = lsm_link_sla_set(link_key, sla_spec);
+
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string,
+            "{\"operation\": \"sla_set\", \"success\": true, \"results\": [], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+static tb_rc json_sla_get(tb_pkt_deprec_t * rx_frame, lsm_link_key_t * link_key,
+                          lsm_link_sla_spec_t * sla_spec)
+{
+    tb_rc rc = lsm_link_sla_get(link_key, sla_spec);
+
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"sla_get\", \"success\": true, \"results\": [");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"cir\": \"%u\", \"eir\": \"%u\"}", (unsigned int)sla_spec->cir_Kbps,
+            (unsigned int)sla_spec->eir_Kbps);
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+static tb_rc json_flows_add(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key,
+                            sw_rec_key_t * sw_rec_key, port_vlan_op_cfg_t port_vlan_op_cfg)
+{
+    tb_rc rc = TB_RC_OK;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    rc = sw_associate_port(sw_rec_key, ifc_key, port_vlan_op_cfg);
+    if (rc != TB_RC_OK) {
+        TB_INFO("%s:%d Failed sw_associate.", __FUNCTION__, __LINE__);
+    }
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    if ((rc == TB_RC_OK) || (rc == TB_RC_ALREADY)) {
+        sprintf(tmp_string, "{\"operation\": \"flows_add\", \"success\": true, \"results\": [");
+    } else {
+        sprintf(tmp_string, "{\"operation\": \"flows_add\", \"success\": false, \"results\": [");
+    }
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+static tb_rc json_flows_delete(tb_pkt_deprec_t * rx_frame, tb_ifc_key_t * ifc_key,
+                              sw_rec_key_t * sw_rec_key)
+{
+    tb_rc rc = TB_RC_OK;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    rc = sw_dissociate_port(sw_rec_key, ifc_key);
+    if (rc != TB_RC_OK) {
+        tb_printf("%s:%d Failed sw_deassociate. (rc=%d)\n", __FUNCTION__, __LINE__, rc);
+    }
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    if ((rc == TB_RC_OK) || (rc == TB_RC_ALREADY)) {
+        sprintf(tmp_string, "{\"operation\": \"flows_delete\", \"success\": true, \"results\": [");
+    } else {
+        sprintf(tmp_string, "{\"operation\": \"flows_delete\", \"success\": false, \"results\": [");
+    }
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+#define MAX_SWITCHING_RECORDS 20        /* for now... */
+static tb_rc json_flows_get(tb_pkt_deprec_t * rx_frame)
+{
+    tb_rc rc = TB_RC_OK;
+    int i, j = 0;
+    int num_switching_records = 0;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    sw_rec_key_t switching_record[MAX_SWITCHING_RECORDS];
+    tb_port_key_t ports_per_record[MAX_SWITCHING_RECORDS][MAX_REPORTABLE_PORTS_PER_SW_RECORD];
+    tb_mac_address_str_t mac_str = "";
+
+    memset(switching_record, 0, sizeof(sw_rec_key_t) * MAX_SWITCHING_RECORDS);
+    memset(ports_per_record, 0,
+           sizeof(tb_port_key_t) * MAX_SWITCHING_RECORDS * MAX_REPORTABLE_PORTS_PER_SW_RECORD);
+
+    num_switching_records =
+        sw_report_all_sw_rec_mgmt(MAX_SWITCHING_RECORDS, switching_record,
+                                  MAX_REPORTABLE_PORTS_PER_SW_RECORD, ports_per_record);
+
+    if (num_switching_records >= MAX_SWITCHING_RECORDS) {
+        TB_ERROR("Out of bounds error, more swr than memory allocated");
+    } else if (num_switching_records < 0) {
+        TB_TRACE("I: (%s:%d)", __FUNCTION__, __LINE__);
+        return (rc = TB_RC_INTERNAL_ERROR);
+    }
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    if (num_switching_records) {
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        if ((rc == TB_RC_OK) || (rc == TB_RC_ALREADY)) {
+            sprintf(tmp_string, "{\"operation\": \"flows\", \"success\": true, \"results\": [");
+        } else {
+            sprintf(tmp_string, "{\"operation\": \"flows\", \"success\": false, \"results\": [");
+        }
+        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+        for (i = 0; i < num_switching_records; i++) {
+            if (i >= 1) {
+                memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                sprintf(tmp_string, ",");
+                json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+            }
+            for (j = 0; j < MAX_REPORTABLE_PORTS_PER_SW_RECORD; j++) {
+                tb_port_type_t  type = ports_per_record[i][j].port_type;
+                /* printf("MGMT_JSON[%d][%d]: port type %u\n", i, j, type); */
+                if (type && (j >= 1)) {
+                    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                    sprintf(tmp_string, ",");
+                    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+                }
+
+                switch (type) {
+                    case tb_port_type_eth_dn: {
+                        tb_ifc_key_t          *ifc_key = &ports_per_record[i][j].key.ifc;
+                        lsm_link_key_t        link_key;
+                        port_vlan_op_cfg_t    port_vlan_op_cfg;
+                        port_vlan_op_cfg_t    *p_vlan_op_cfg;
+
+                        /* ingress switch record */
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        sprintf(tmp_string, "{\"ingress_switch_record\": {\"svid\": \"%05d\", \"cvid\": \"%05d\"},",
+                                switching_record[i].outer_vid, switching_record[i].inner_vid);
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        /* ingress port */
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        sprintf(tmp_string, "\"ingress_port\": {\"iinst\": \"%d\", \"itype\": \"eth\"},",
+                                ifc_key->inst);
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        /* egress port */
+                        rc = hal_find_link_key_by_llid(switching_record[i].default_dest, &link_key);
+                        if (rc != TB_RC_OK) {
+                            TB_ERROR("find link key failed");
+                        }
+
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        tb_mac_address_to_str(link_key.mac.u8, mac_str);
+                        sprintf(tmp_string, "\"egress_port\": {\"iinst\": \"%d\", \"itype\": \"olt\", \"macid\": \"%s\"},",
+                                link_key.ifc_inst, mac_str);
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        /* vlan operation */
+                        memset(&port_vlan_op_cfg, 0, sizeof(port_vlan_op_cfg));
+
+                        p_vlan_op_cfg = sw_find_port_vlan_op_cfg(&switching_record[i],
+                                                                 &ports_per_record[i][0], /* single ports right now */
+                                                                 &port_vlan_op_cfg);
+
+                        if (p_vlan_op_cfg == NULL) {
+                            TB_ERROR("p_vlan_op_cfg is NULL");
+                        }
+
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        if ((port_vlan_op_cfg[0].op_type != port_vlan_op_type_unspecified) &&
+                            (port_vlan_op_cfg[0].op_type != port_vlan_op_type_none)) {
+                            /* STAG */
+                            sprintf(tmp_string, "\"operation\": ");
+                            switch (port_vlan_op_cfg[0].op_type) {
+                                case port_vlan_op_type_push:
+                                    sprintf(tmp_string + 13, "{\"code\": \"push\", \"tpid\": \"88a8\", \"vid\": \"%d\"}",
+                                            port_vlan_op_cfg[0].op_arg);
+                                    break;
+                                case port_vlan_op_type_pop:
+                                    sprintf(tmp_string + 13, "{\"code\": \"pop\", \"tpid\": \"88a8\"}");
+                                    break;
+                                case port_vlan_op_type_none:
+                                    sprintf(tmp_string + 13, "{\"code\": \"none\", \"tpid\": \"88a8\"}");
+                                    break;
+                                default:
+                                case port_vlan_op_type_translate:
+                                case port_vlan_op_type_count:
+                                case port_vlan_op_type_unspecified:
+                                    TB_TRACE("stag unspecified");
+                                    break;
+                            }
+                        } else if ((port_vlan_op_cfg[1].op_type != port_vlan_op_type_unspecified) &&
+                                   (port_vlan_op_cfg[0].op_type != port_vlan_op_type_none)) {
+                            /* CTAG */
+                            sprintf(tmp_string, "\"operation\": ");
+                            switch (port_vlan_op_cfg[1].op_type) {
+                                case port_vlan_op_type_push:
+                                    sprintf(tmp_string + 13, "{\"code\": \"push\", \"tpid\": \"8100\", \"vid\": \"%d\"}",
+                                            port_vlan_op_cfg[1].op_arg);
+                                    break;
+                                case port_vlan_op_type_pop:
+                                    sprintf(tmp_string + 13, "{\"code\": \"pop\", \"tpid\": \"8100\"}");
+                                    break;
+                                case port_vlan_op_type_none:
+                                    sprintf(tmp_string + 13, "{\"code\": \"none\", \"tpid\": \"8100\"}");
+                                    break;
+                                default:
+                                case port_vlan_op_type_translate:
+                                case port_vlan_op_type_count:
+                                case port_vlan_op_type_unspecified:
+                                    TB_TRACE("ctag unspecified");
+                                    break;
+                            }
+                        }
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        sprintf(tmp_string, "}");
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        break;
+                    }
+                    case tb_port_type_llid_up: {
+                        lsm_link_key_str_t  link_key_str;
+                        lsm_link_key_t      *link_key = &ports_per_record[i][j].key.link;
+                        tb_ifc_subinst_t      llid    = lsm_find_llid_by_link_key(link_key);
+                        port_vlan_op_cfg_t    port_vlan_op_cfg;
+                        port_vlan_op_cfg_t    *p_vlan_op_cfg;
+                        lsm_link_key_llid_to_str(link_key, llid, link_key_str);
+
+                        /* ingress switch record */
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        sprintf(tmp_string, "{\"ingress_switch_record\": {\"svid\": \"%05d\", \"cvid\": \"%05d\"},",
+                                switching_record[i].outer_vid, switching_record[i].inner_vid);
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+
+                        /* ingress port */
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        tb_mac_address_to_str(link_key->mac.u8, mac_str);
+                        sprintf(tmp_string, "\"ingress_port\": {\"iinst\": \"%d\", \"itype\": \"olt\", \"macid\": \"%s\"},",
+                                link_key->ifc_inst, mac_str);
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        /* egress port */
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        sprintf(tmp_string, "\"egress_port\": {\"iinst\": \"0\", \"itype\": \"eth\"},");
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        /* vlan operation */
+                        memset(&port_vlan_op_cfg, 0, sizeof(port_vlan_op_cfg));
+                        p_vlan_op_cfg = sw_find_port_vlan_op_cfg(&switching_record[i],
+                                                                 &ports_per_record[i][0], /* single ports right now */
+                                                                 &port_vlan_op_cfg);
+
+                        if (p_vlan_op_cfg == NULL) {
+                            TB_ERROR("p_vlan_op_cfg is NULL");
+                        }
+
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        if (port_vlan_op_cfg[0].op_type != port_vlan_op_type_unspecified) {
+                            /* STAG */
+                            sprintf(tmp_string, "\"operation\": ");
+                            switch (port_vlan_op_cfg[0].op_type) {
+                                case port_vlan_op_type_push:
+                                    sprintf(tmp_string + 13, "{\"code\": \"push\", \"tpid\": \"88a8\", \"vid\": \"%d\"}",
+                                            port_vlan_op_cfg[0].op_arg);
+                                    break;
+                                case port_vlan_op_type_pop:
+                                    sprintf(tmp_string + 13, "{\"code\": \"pop\", \"tpid\": \"88a8\"}");
+                                    break;
+                                case port_vlan_op_type_none:
+                                    sprintf(tmp_string + 13, "{\"code\": \"none\", \"tpid\": \"88a8\"}");
+                                    break;
+                                default:
+                                case port_vlan_op_type_translate:
+                                case port_vlan_op_type_count:
+                                case port_vlan_op_type_unspecified:
+                                    break;
+                            }
+                        } else if (port_vlan_op_cfg[1].op_type != port_vlan_op_type_unspecified) {
+                            /* CTAG */
+                            sprintf(tmp_string, "\"operation\": ");
+                            switch (port_vlan_op_cfg[1].op_type) {
+                                case port_vlan_op_type_push:
+                                    sprintf(tmp_string + 13, "{\"code\": \"push\", \"tpid\": \"8100\", \"vid\": \"%d\"}",
+                                            port_vlan_op_cfg[1].op_arg);
+                                    break;
+                                case port_vlan_op_type_pop:
+                                    sprintf(tmp_string + 13, "{\"code\": \"pop\", \"tpid\": \"8100\"}");
+                                    break;
+                                case port_vlan_op_type_none:
+                                    sprintf(tmp_string + 13, "{\"code\": \"none\", \"tpid\": \"8100\"}");
+                                    break;
+                                default:
+                                case port_vlan_op_type_translate:
+                                case port_vlan_op_type_count:
+                                case port_vlan_op_type_unspecified:
+                                    break;
+                            }
+                        }
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+                        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+                        sprintf(tmp_string, "}");
+                        json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+                        break;
+                    }
+                    default:
+                        rc = TB_RC_INTERNAL_ERROR;
+                        break;
+                } // switch
+            }
+        }
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        sprintf(tmp_string, "], \"error\": null}");
+        json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    } else {
+        memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+        sprintf(tmp_string, "{\"operation\": \"flows\", \"success\": true, \"results\": [], \"error\": null}");
+        json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+    }
+
+    return rc;
+}
+
+static tb_rc json_mode_set(tb_pkt_deprec_t * rx_frame, mandata_pon_type_t PON)
+{
+    tb_rc rc = TB_RC_OK;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+    unsigned int serial_number = 0;
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"mode_set\", \"success\": true, \"results\": [");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    sleep_ms(20);
+
+    /* Only change if we not currently at the requested mode */
+    if (tbg.PON != PON) {
+        rc = hwsys_manufacturing_pon_write(PON);
+        if (rc == 0) {
+            rc = hwsys_manufacturing_pon_read(&tbg.PON);
+            if (rc != 0) {
+                tb_printf("E: PON read error (%s:%d)\n", __FILE__, __LINE__);
+            }
+
+            /* if the PON type changes, re-write the mac addresses */
+            hwsys_manufacturing_serial_read(&serial_number);
+            set_sernum_and_mac_address(serial_number);
+
+            hw_reset(); /* RESET the BITSTREAM */
+        }
+    }
+    return rc;
+}
+
+static tb_rc json_cli_cmd(tb_pkt_deprec_t * rx_frame)
+{
+    tb_rc rc = TB_RC_OK;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "{\"operation\": \"cli\", \"success\": true, \"results\": [");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "], \"error\": null}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+
+    return rc;
+}
+
+typedef struct {
+    uint32   image_length;
+    uint32   crc32_expected;
+    uint32   crc32_actual;
+} image_header_t;
+
+// [tibit@tibit-ubuntu-vm-pow] /opt/tbos.git $ cat /tmp/hello.txt
+// hello, world!
+// [tibit@tibit-ubuntu-vm-pow] /opt/tbos.git $ od -t x1 /tmp/hello.txt
+// 0000000 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 0a
+// [tibit@tibit-ubuntu-vm-pow] /opt/tbos.git $ crc32 /tmp/hello.txt
+// b631dfc0
+// [tibit@tibit-ubuntu-vm-pow] /opt/tbos.git $ wc -c /tmp/hello.txt
+// 14 /tmp/hello.txt
+
+static int process_copy(const uint8_t *msg_buf, UNUSED_ARG uint32 msg_len)
+{
+    const uint8_t *image_start           = (const uint8_t *)0x81000000;
+    const uint8_t *image_length_packed   = msg_buf;
+    const uint8_t *crc32_expected_packed = msg_buf + 4;
+    uint32         crc32_expected        = tb_unpack_u32(crc32_expected_packed);
+    uint32         image_length          = tb_unpack_u32(image_length_packed);
+    uint32         crc32_actual          = crc32(image_start, image_length);
+
+    TB_WARNING("[copy] image_length %u  crc32_expected 0x%08x   crc32_actual 0x%08x", image_length, crc32_expected, crc32_actual);
+    if (crc32_expected == crc32_actual) {
+        image_header_t *header = (image_header_t *)(image_start - sizeof(image_header_t));
+
+        TB_WARNING("-> writing image header");
+        header->image_length   = image_length;
+        header->crc32_expected = crc32_expected;
+        header->crc32_actual   = 0; // calculated & compared w/ expected value by U-Boot script
+
+        tb_dbug_hexdump_one_line(TB_DBUG_LVL_WARNING, __FUNCTION__, __LINE__, header, 0, 32, "header+image: ", " ...");
+    } else {
+        TB_ERROR("crc32_expected 0x%08x != crc32_actual 0x%08x", crc32_expected, crc32_actual);
+    }
+
+    return 0;
+}
+
+static int process_dnld(const uint8_t *msg_buf, uint32 msg_len)
+{
+    const uint8_t *start_offset_packed    = msg_buf;
+    const uint8_t *fragment_length_packed = msg_buf + 4;
+    const uint8_t *fragment_start         = msg_buf + 8;
+    uint32         start_offset           = tb_unpack_u32(start_offset_packed);
+    uint32         fragment_length        = tb_unpack_u32(fragment_length_packed);
+    uint8_t       *dest_buf               = (uint8_t *)0x81000000;
+
+    TB_WARNING("[dnld] memcpy(%p, %p, %u)", dest_buf+start_offset, fragment_start, fragment_length);
+    tb_dbug_hexdump_one_line(TB_DBUG_LVL_WARNING, __FUNCTION__, __LINE__, msg_buf, 0, msg_len, "msg_buf: ", NULL);
+    tb_dbug_hexdump_one_line(TB_DBUG_LVL_WARNING, __FUNCTION__, __LINE__, fragment_start, 0, fragment_length, "fragment: ", NULL);
+    memcpy(dest_buf+start_offset, fragment_start, fragment_length);
+
+    return 0;
+}
+
+int json_send_response(char *type, char *buffer, uint16_t bufflen)
+{
+    tb_pkt_deprec_t *rx_frame = &fake_frame;
+    char tmp_string[SIZE_OF_TMP_STRING] = { '\0' };
+
+    memset(rx_frame, 0, sizeof(*rx_frame));
+
+    memset(global_json_string, 0, SIZE_OF_JSON_STRING);
+    json_str_append_and_out(global_json_string, tmp_string, RESET, rx_frame);
+
+    // Add the header
+    sprintf(tmp_string, "{\"operation\": \"%s\", \"success\": true, \"results\": {", type);
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    if (bufflen > SIZE_OF_JSON_STRING) {
+        json_error(rx_frame, BRDG_RET_NOT_OK);
+        return 0;
+    }
+
+    // Add the attribute values
+    json_str_append_and_out(global_json_string, buffer, APPEND, rx_frame);
+
+    // Add the trailer
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}, ");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "\"error\": null");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND, rx_frame);
+
+    memset(tmp_string, 0, SIZE_OF_TMP_STRING);
+    sprintf(tmp_string, "}");
+    json_str_append_and_out(global_json_string, tmp_string, APPEND_AND_FLUSH_CR, rx_frame);
+    return 0;
+}
+
+
+
+static int process_json(tb_pkt_deprec_t * rx_frame)
+{
+    int r;
+    int eof_expected = 0;
+    char *js = NULL;
+    size_t jslen = 0;
+    char buf[TB_PKT_DEPREC_PAYLOAD_BYTES];
+    jsmn_parser p;
+    jsmntok_t *tok;
+    size_t tokcount = 2;
+    unsigned int json_length = 0;
+
+    jsmn_init(&p);
+
+    /* Allocate some tokens as a start */
+    tok = malloc(sizeof(*tok) * tokcount);
+    if (tok == NULL) {
+        printf("malloc(): errno=%d\n", errno);
+        return 3;
+    }
+
+    memset(buf, 0, sizeof(buf));
+#ifdef USE_VLAN_HEADER_INCOMING
+    json_length = (rx_frame->num_bytes - START_OF_JSON_VLAN - FRAME_CRC_SIZE);
+    strncpy(buf, (const char *)&rx_frame->preamble_start[START_OF_JSON_VLAN], json_length);
+#else
+    json_length = (rx_frame->num_bytes - START_OF_JSON_UNTAGGED - FRAME_CRC_SIZE);
+    strncpy(buf, (const char *)&rx_frame->preamble_start[START_OF_JSON_UNTAGGED], json_length);
+#endif
+    r = strlen(buf);
+    /* tb_printf("STRLEN:[%d] %s\n", r, buf); */
+
+    if (r <= 0) {
+        if (tok != NULL) { free(tok); }
+        if (js  != NULL) { free(js);  }
+    if (r < 0) {
+        printf("fread(): %d, errno=%d\n", r, errno);
+        return 1;
+    }
+    if (r == 0) {
+        if (eof_expected != 0) {
+            return 0;
+        } else {
+            printf("fread(): unexpected EOF\n");
+            return 2;
+        }
+    }
+    }
+
+    js = realloc(js, jslen + r + 1);
+    if (js == NULL) {
+        printf("realloc(): errno=%d\n", errno);
+        if (tok != NULL) { free(tok); }
+        return 3;
+    }
+    strncpy(js + jslen, buf, r);
+    jslen = jslen + r;
+
+ again:
+    r = jsmn_parse(&p, js, jslen, tok, tokcount);
+    if (r < 0) {
+        if (r == JSMN_ERROR_NOMEM) {
+            tokcount = tokcount * 2;
+            tok = realloc(tok, sizeof(*tok) * tokcount);
+            if (tok == NULL) {
+                printf("realloc(): errno=%d\n", errno);
+                if (js != NULL) { free(js); }
+                return 3;
+            }
+            goto again;
+        }
+    } else {
+        /* This is the starting point for processing a JSON frame */
+        /* tb_printf("START_JSON_PARSE\n"); */
+        dump(js, tok, p.toknext, 0);
+        eof_expected = 1;
+    }
+
+    if (tok != NULL) { free(tok); }
+    if (js  != NULL) { free(js);  }
+
+    if (strlen(operation) != 0) {
+        if (strcmp(operation, "version") == 0) {
+            json_version(rx_frame);
+        } else if (strcmp(operation, "interfaces") == 0) {
+            json_interfaces(rx_frame);
+        } else if (strcmp(operation, "links") == 0) {
+            json_links(rx_frame, itype, strtoul(iinst, NULL, 10));
+        } else if (strcmp(operation, "register_read") == 0) {
+            if (strlen(location) == 0) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                json_register_read(rx_frame, strtoul(location, NULL, 16));
+            }
+        } else if (strcmp(operation, "register_write") == 0) {
+            if (strlen(location) == 0) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                json_register_write(rx_frame, strtoul(location, NULL, 16),
+                                    strtoul(value, NULL, 16));
+            }
+        } else if (strcmp(operation, "stats") == 0) {
+            if ((strlen(itype) == 0) || (strlen(iinst) == 0) || (strlen(mac) == 0)) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                uint16_t lidx = 0;
+                /* tb_ifc_key_t    ifc_key = { .type = TB_IFC_TYPE_OLT, */
+                /*                             .inst = strtoul(iinst,NULL,10) }; */
+                lsm_link_key_t link_key = {.ifc_type = TB_IFC_TYPE_OLT,
+                    .ifc_inst = strtoul(iinst, NULL, 10)
+                };
+                /* hal_ifc_hw_cfg *hw_cfg; */
+
+                if (0 == strcmp("olt", itype)) {
+                    /* ifc_key.type  = TB_IFC_TYPE_OLT; */
+                    link_key.ifc_type = TB_IFC_TYPE_OLT;
+                    if (gpon_device_p()) {
+                        link_key.ifc_type = TB_IFC_TYPE_ALLOC_ID;
+                    }
+                } else if (0 == strcmp("onu", itype)) {
+                    /* ifc_key.type  = TB_IFC_TYPE_ONU; */
+                    link_key.ifc_type = TB_IFC_TYPE_ONU;
+                }
+                /* hw_cfg = hal_get_hw_cfg_by_key(ifc_key); */
+
+
+                memcpy(link_key.mac.u8, mac_addr.u8, sizeof(link_key.mac));
+                if (TB_RC_OK != hal_find_lidx_by_link_key(&link_key, &lidx)) {
+                    TB_ERROR("link not found");
+                    // Nathan: json_error(rx_frame, BRDG_RET_INPUT_INVALID); ??
+                }
+                TB_TRACE("LIDX: %d", lidx);
+
+                /* Warning: Should derive the mac block from hw_cfg */
+                json_stats(rx_frame, lidx, MB1);
+            }
+        } else if (strcmp(operation, "sla_set") == 0) {
+            if ((strlen(itype) == 0) || (strlen(iinst) == 0) || (strlen(mac) == 0)
+                || (strlen(cir) == 0) || (strlen(eir) == 0)) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                if (0 != strcmp("olt", itype)) {
+                    json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+                } else {
+                    lsm_link_sla_spec_t sla_spec = {.cir_Kbps = strtoul(cir, NULL, 10),
+                        .eir_Kbps = strtoul(eir, NULL, 10)
+                    };
+                    lsm_link_key_t link_key = {.ifc_type = TB_IFC_TYPE_OLT,
+                        .ifc_inst = strtoul(iinst, NULL, 10)
+                    };
+
+                    memcpy(link_key.mac.u8, mac_addr.u8, sizeof(link_key.mac));
+
+                    tb_rc rc = json_sla_set(rx_frame, &link_key, &sla_spec);
+
+                    TB_TRACE("json_sla_set returned %d (%s)", rc, tb_strerror(rc));
+                }
+            }
+        } else if (strcmp(operation, "sla_get") == 0) {
+            if ((strlen(itype) == 0) || (strlen(iinst) == 0) || (strlen(mac) == 0)) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                if (0 != strcmp("olt", itype)) {
+                    json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+                } else {
+                    tb_mac_address_str_t mac_str;
+                    lsm_link_sla_spec_t sla_spec;
+                    lsm_link_key_t link_key = {.ifc_type = TB_IFC_TYPE_OLT,
+                        .ifc_inst = strtoul(iinst, NULL, 10)
+                    };
+
+                    memcpy(link_key.mac.u8, mac_addr.u8, sizeof(link_key.mac));
+
+                    tb_mac_address_to_str(link_key.mac.u8, mac_str);
+
+                    tb_rc rc = json_sla_get(rx_frame, &link_key, &sla_spec);
+
+                    TB_TRACE("json_sla_get returned %d (%s)", rc, tb_strerror(rc));
+                }
+            }
+        } else if (strcmp(operation, "fec_set") == 0) {
+            if ((strlen(mode) == 0)) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                tb_rc rc = TB_RC_OK;
+                tb_ifc_key_t ifc_key = {.type = TB_IFC_TYPE_OLT,
+                                        .inst = 0,
+                                        .subinst = TB_IFC_SUBINST_NONE
+                };
+
+                if (strncmp(mode, "enabled", 7) == 0) {
+                    rc = json_fec_set(rx_frame, &ifc_key, true);
+                } else {
+                    rc = json_fec_set(rx_frame, &ifc_key, false);
+                }
+
+                TB_TRACE("json_fec_set returned %d (%s)", rc, tb_strerror(rc));
+            }
+        } else if (strcmp(operation, "fec_get") == 0) {
+            tb_ifc_key_t ifc_key = {.type = TB_IFC_TYPE_OLT,
+                                    .inst = 0,
+                                    .subinst = TB_IFC_SUBINST_NONE
+            };
+
+            tb_rc rc = json_fec_get(rx_frame, &ifc_key);
+
+            TB_TRACE("json_fec_get returned %d (%s)", rc, tb_strerror(rc));
+
+        } else if (strcmp(operation, "tag_mode_set") == 0) {
+            if ((strlen(tag_mode) == 0)) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                tb_rc rc = TB_RC_OK;
+
+                rc = json_tag_mode_set(rx_frame, tag_mode);
+
+
+                TB_TRACE("json_tag_mode_set returned %d (%s)", rc, tb_strerror(rc));
+            }
+        } else if (strcmp(operation, "tag_mode_get") == 0) {
+
+            tb_rc rc = TB_RC_OK;
+
+            rc = json_tag_mode_get(rx_frame);
+
+            TB_TRACE("json_tag_mode_get returned %d (%s)", rc, tb_strerror(rc));
+
+        } else if (strcmp(operation, "flows_add") == 0) {
+            if ((strlen(itype) == 0) || (strlen(iinst) == 0) || (strlen(mac) == 0)
+                || (strlen(svid) == 0) || (strlen(cvid) == 0)
+                || (strlen(code) == 0)) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                sw_rec_key_t sw_rec_key = { .outer_vid = strtoul(svid, NULL, 10),
+                                            .inner_vid = strtoul(cvid, NULL, 10)
+                };
+                tb_ifc_key_t ingress_ifc_key = {.type = TB_IFC_TYPE_UNKNOWN,
+                                                .inst = strtoul(iinst, NULL, 10),
+                                                .subinst = TB_IFC_SUBINST_NONE
+                };
+                lsm_link_key_t link_key = {.ifc_type = TB_IFC_TYPE_OLT,
+                                           .ifc_inst = strtoul(iinst, NULL, 10)
+                };
+                port_vlan_op_cfg_t port_vlan_op_cfg = {
+                    { port_vlan_op_type_unspecified, 0 },
+                    { port_vlan_op_type_unspecified, 0 }
+                };
+
+                if (strncmp(tpid, "88a8", 5) == 0) {
+                    if (strncmp(code, "pop", 4) == 0) {
+                        port_vlan_op_cfg[0].op_type = port_vlan_op_type_pop;
+                        TB_TRACE("setting stag pop");
+
+                    } else if (strncmp(code, "push", 4) == 0) {
+                        port_vlan_op_cfg[0].op_type = port_vlan_op_type_push;
+                        port_vlan_op_cfg[0].op_arg = strtoul(vid, NULL, 10);
+                        TB_TRACE("setting stag push");
+                    }
+                } else if (strncmp(tpid, "8100", 5) == 0) {
+                    if (strncmp(code, "pop", 4) == 0) {
+                        port_vlan_op_cfg[1].op_type = port_vlan_op_type_pop;
+                        TB_TRACE("settting ctag pop");
+
+                    } else if (strncmp(code, "push", 4) == 0) {
+                        port_vlan_op_cfg[1].op_type = port_vlan_op_type_push;
+                        port_vlan_op_cfg[1].op_arg = strtoul(vid, NULL, 10);
+                        TB_TRACE("setting ctag push");
+                    }
+                }
+
+                tb_str_to_buf(link_key.mac.u8, mac, sizeof(mac_addr));
+
+                if (strncmp(itype,"olt", 4) == 0) {
+                    ingress_ifc_key.type = TB_IFC_TYPE_OLT;
+                    /* If ingress type is OLT, then set the subinst to LLID */
+                    ingress_ifc_key.subinst = lsm_find_llid_by_link_key(&link_key);
+                    if (gpon_device_p()) {
+                        ingress_ifc_key.subinst += (0x1000 + BRDG_XGEM_ALLOC_ID_LIDX_THRESHOLD);
+                    }
+
+                } else if (strncmp(itype,"eth", 4) == 0) {
+                    ingress_ifc_key.type = TB_IFC_TYPE_ETHERNET;
+                    if (gpon_device_p()) {
+                        link_key.ifc_type = TB_IFC_TYPE_ALLOC_ID;
+                    }
+                    /* If ingress type is Ethernet, set the default dest to the LLID */
+                    sw_rec_key.default_dest = lsm_find_llid_by_link_key(&link_key);
+                    if (sw_rec_key.default_dest == TB_IFC_SUBINST_NONE) {
+                        if (gpon_device_p()) {
+                            sw_rec_key.default_dest = 0x10000 | 0x10bc; // FIXME temporary hard-coded pseudo-broadcast xgem id
+                        } else {
+                            sw_rec_key.default_dest = 0x10000 | 0x7ffe; // FIXME not sure if we should assume EPON or fail in the EPON case
+                        }
+                    }
+                } else {
+                    tb_printf("UNKNOWN IFC TYPE\n");
+                }
+
+                tb_rc rc = json_flows_add(rx_frame, &ingress_ifc_key, &sw_rec_key,
+                                          port_vlan_op_cfg);
+
+                TB_TRACE("json_flows_add returned %d (%s)", rc, tb_strerror(rc));
+            }
+        } else if (strcmp(operation, "flows_delete") == 0) {
+            if ((strlen(itype) == 0) || (strlen(iinst) == 0) || (strlen(mac) == 0)
+                || (strlen(svid) == 0) || (strlen(cvid) == 0)) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                sw_rec_key_t sw_rec_key = {.outer_vid = strtoul(svid, NULL, 10),
+                                           .inner_vid = strtoul(cvid, NULL, 10)
+                };
+                tb_ifc_key_t ingress_ifc_key = {.type = TB_IFC_TYPE_UNKNOWN,
+                                                .inst = strtoul(iinst, NULL, 10),
+                                                .subinst = TB_IFC_SUBINST_NONE
+                };
+                lsm_link_key_t link_key = {.ifc_type = TB_IFC_TYPE_OLT,
+                                           .ifc_inst = strtoul(iinst, NULL, 10)
+                };
+                tb_str_to_buf(link_key.mac.u8, mac, sizeof(mac_addr));
+
+
+                if (strncmp(itype,"olt", 4) == 0) {
+                    ingress_ifc_key.type = TB_IFC_TYPE_OLT;
+                    /* If ingress type is OLT, then set the subinst to LLID */
+                    ingress_ifc_key.subinst = lsm_find_llid_by_link_key(&link_key);
+                    /*  if (gpon_device_p()) { */
+                    /*     ingress_ifc_key.subinst += (0x1000 + BRDG_XGEM_ALLOC_ID_LIDX_THRESHOLD); */
+                    /* } */
+
+                } else if (strncmp(itype,"eth", 4) == 0) {
+                    ingress_ifc_key.type = TB_IFC_TYPE_ETHERNET;
+                    if (gpon_device_p()) {
+                        link_key.ifc_type = TB_IFC_TYPE_ALLOC_ID;
+                    }
+                    /* If ingress type is Ethernet, set the default dest to the LLID */
+                    sw_rec_key.default_dest = lsm_find_llid_by_link_key(&link_key);
+
+                } else {
+                    tb_printf("UNKNOWN IFC TYPE\n");
+                }
+
+                tb_rc rc = json_flows_delete(rx_frame, &ingress_ifc_key, &sw_rec_key);
+
+                TB_TRACE("json_flows_delete returned %d (%s)", rc, tb_strerror(rc));
+            }
+        } else if (strcmp(operation, "flows") == 0) {
+            tb_rc rc = json_flows_get(rx_frame);
+            TB_TRACE("json_flows_get returned %d (%s)", rc, tb_strerror(rc));
+        } else if (strcmp(operation, "mode_set") == 0) {
+            if (strlen(mode) == 0) {
+                json_error(rx_frame, BRDG_RET_INPUT_INVALID);
+            } else {
+                tb_rc rc = TB_RC_OK;
+
+                if (strncmp(mode, "GPON", 5) == 0) {
+                    if (olt_device_p()) {
+                        rc = json_mode_set(rx_frame, MANDATA_PON_TYPE_10G_GPON_OLT);
+                    } else {
+                        rc = json_mode_set(rx_frame, MANDATA_PON_TYPE_10G_GPON_ONU);
+                    }
+                } else if (strncmp(mode, "EPON", 5) == 0) {
+                    if (olt_device_p()) {
+                        rc = json_mode_set(rx_frame, MANDATA_PON_TYPE_10G_EPON_OLT);
+                    } else {
+                        rc = json_mode_set(rx_frame, MANDATA_PON_TYPE_10G_EPON_ONU);
+                    }
+                } else {
+                    TB_WARNING("Unrecognized mode %s", mode);
+                }
+                TB_TRACE("json_mode_set returned %d (%s)", rc, tb_strerror(rc));
+            }
+        } else if (strcmp(operation, "cli") == 0) {
+            run_command(cmd, 0);
+            json_cli_cmd(rx_frame);
+        } else if (strcmp(operation, "getRequest") == 0) {
+            mac_address deviceMac;
+            tb_str_to_buf(deviceMac.u8, mac, sizeof(mac_addr));
+            oam_snd_get_request(&deviceMac);
+        } else {
+            TB_WARNING("unknown operation \"%s\" -- ignoring", operation);
+        }
+
+        memset(operation, 0, SIZE_OF_OPERATION);
+        memset(itype, 0, SIZE_OF_ITYPE);
+        memset(iinst, 0, SIZE_OF_IINST);
+        memset(svid, 0, SVID_STR_LEN);
+        memset(cvid, 0, CVID_STR_LEN);
+        memset(cmd, 0, SIZE_OF_CMD);
+    }
+
+    return 0;
+
+}                               /* process_json() */
+
+/* JSON input mode
+ *
+ * Syntax:
+ *  json
+ */
+static int do_json(UNUSED_ARG cmd_tbl_t * cmdtp, UNUSED_ARG int flag, UNUSED_ARG int argc, char *const argv[])
+{
+    tb_pkt_deprec_t *p_fake_frame;
+    tb_dbug_lvl_t    original_dbug_lvl;
+    p_fake_frame = &fake_frame;
+
+    memset(p_fake_frame, 0, sizeof(tb_pkt_deprec_t));
+    /* No spaces allowed during json input on the command line or else
+     * the json is considered as more then one argument (argc > 2) */
+    p_fake_frame->num_bytes = 8 /* preamble */
+        + 6                     /* dest  */
+        + 6                     /* source */
+        + 2                     /* type */
+        + 4                     /* 'json' */
+        + 1                     /* space  */
+        + strlen(argv[1])
+        + 4;                    /* CRC */
+    memcpy(&p_fake_frame->preamble_start[START_OF_JSON_UNTAGGED], argv[1], strlen(argv[1]));
+    command_line_json = true;
+
+    /* silence debug while we process a command */
+    original_dbug_lvl = tb_dbug_lvl;
+    if ((tb_dbug_lvl == TB_DBUG_LVL_ERROR) || (tb_dbug_lvl == TB_DBUG_LVL_WARNING)) {
+        tb_dbug_lvl = TB_DBUG_LVL_SILENT;
+    }
+
+    process_json(p_fake_frame);
+    tb_dbug_lvl = original_dbug_lvl;
+    return 0;
+}                               /* do_json */
+
+/**************************************************/
+U_BOOT_CMD(json, 2, 0, do_json, "enter json mode", "\r\n");
diff --git a/voltha/adapters/tibit_olt/tibit_olt.py b/voltha/adapters/tibit_olt/tibit_olt.py
index 5d9ab81..9b2964b 100644
--- a/voltha/adapters/tibit_olt/tibit_olt.py
+++ b/voltha/adapters/tibit_olt/tibit_olt.py
@@ -329,8 +329,9 @@
             # later use.  The linkid is the macid returned.
             self.vlan_to_device_ids[vlan_id] = (device.id, device.parent_id, macid.get('macid', 0))
 
-        # Give the ONUs a chance to arrive before starting metric collection
-        reactor.callLater(5.0, self.start_kpi_collection, device.id)
+        ### KPI Metrics - Work in progress feature - Disabling for now 
+        ### Give the ONUs a chance to arrive before starting metric collection
+        ###    reactor.callLater(5.0, self.start_kpi_collection, device.id)
 
     def _olt_side_onu_activation(self, serial):
         """
