diff --git a/api/.gitignore b/api/.gitignore
deleted file mode 100644
index 8a058c3..0000000
--- a/api/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-**/*.pb.go
-**/*.pb.gw.go
\ No newline at end of file
diff --git a/api/bbsim/bbsim.pb.go b/api/bbsim/bbsim.pb.go
new file mode 100644
index 0000000..7226f79
--- /dev/null
+++ b/api/bbsim/bbsim.pb.go
@@ -0,0 +1,992 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: api/bbsim/bbsim.proto
+
+package bbsim
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type PONPort struct {
+	ID                   int32    `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
+	OperState            string   `protobuf:"bytes,2,opt,name=OperState,proto3" json:"OperState,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *PONPort) Reset()         { *m = PONPort{} }
+func (m *PONPort) String() string { return proto.CompactTextString(m) }
+func (*PONPort) ProtoMessage()    {}
+func (*PONPort) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{0}
+}
+
+func (m *PONPort) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PONPort.Unmarshal(m, b)
+}
+func (m *PONPort) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PONPort.Marshal(b, m, deterministic)
+}
+func (m *PONPort) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PONPort.Merge(m, src)
+}
+func (m *PONPort) XXX_Size() int {
+	return xxx_messageInfo_PONPort.Size(m)
+}
+func (m *PONPort) XXX_DiscardUnknown() {
+	xxx_messageInfo_PONPort.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PONPort proto.InternalMessageInfo
+
+func (m *PONPort) GetID() int32 {
+	if m != nil {
+		return m.ID
+	}
+	return 0
+}
+
+func (m *PONPort) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+type NNIPort struct {
+	ID                   int32    `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
+	OperState            string   `protobuf:"bytes,2,opt,name=OperState,proto3" json:"OperState,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *NNIPort) Reset()         { *m = NNIPort{} }
+func (m *NNIPort) String() string { return proto.CompactTextString(m) }
+func (*NNIPort) ProtoMessage()    {}
+func (*NNIPort) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{1}
+}
+
+func (m *NNIPort) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_NNIPort.Unmarshal(m, b)
+}
+func (m *NNIPort) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_NNIPort.Marshal(b, m, deterministic)
+}
+func (m *NNIPort) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NNIPort.Merge(m, src)
+}
+func (m *NNIPort) XXX_Size() int {
+	return xxx_messageInfo_NNIPort.Size(m)
+}
+func (m *NNIPort) XXX_DiscardUnknown() {
+	xxx_messageInfo_NNIPort.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NNIPort proto.InternalMessageInfo
+
+func (m *NNIPort) GetID() int32 {
+	if m != nil {
+		return m.ID
+	}
+	return 0
+}
+
+func (m *NNIPort) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+type Olt struct {
+	ID                   int32      `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
+	SerialNumber         string     `protobuf:"bytes,2,opt,name=SerialNumber,proto3" json:"SerialNumber,omitempty"`
+	OperState            string     `protobuf:"bytes,3,opt,name=OperState,proto3" json:"OperState,omitempty"`
+	InternalState        string     `protobuf:"bytes,4,opt,name=InternalState,proto3" json:"InternalState,omitempty"`
+	NNIPorts             []*NNIPort `protobuf:"bytes,5,rep,name=NNIPorts,proto3" json:"NNIPorts,omitempty"`
+	PONPorts             []*PONPort `protobuf:"bytes,6,rep,name=PONPorts,proto3" json:"PONPorts,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
+	XXX_unrecognized     []byte     `json:"-"`
+	XXX_sizecache        int32      `json:"-"`
+}
+
+func (m *Olt) Reset()         { *m = Olt{} }
+func (m *Olt) String() string { return proto.CompactTextString(m) }
+func (*Olt) ProtoMessage()    {}
+func (*Olt) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{2}
+}
+
+func (m *Olt) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Olt.Unmarshal(m, b)
+}
+func (m *Olt) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Olt.Marshal(b, m, deterministic)
+}
+func (m *Olt) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Olt.Merge(m, src)
+}
+func (m *Olt) XXX_Size() int {
+	return xxx_messageInfo_Olt.Size(m)
+}
+func (m *Olt) XXX_DiscardUnknown() {
+	xxx_messageInfo_Olt.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Olt proto.InternalMessageInfo
+
+func (m *Olt) GetID() int32 {
+	if m != nil {
+		return m.ID
+	}
+	return 0
+}
+
+func (m *Olt) GetSerialNumber() string {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return ""
+}
+
+func (m *Olt) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+func (m *Olt) GetInternalState() string {
+	if m != nil {
+		return m.InternalState
+	}
+	return ""
+}
+
+func (m *Olt) GetNNIPorts() []*NNIPort {
+	if m != nil {
+		return m.NNIPorts
+	}
+	return nil
+}
+
+func (m *Olt) GetPONPorts() []*PONPort {
+	if m != nil {
+		return m.PONPorts
+	}
+	return nil
+}
+
+type ONU struct {
+	ID                   int32    `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
+	SerialNumber         string   `protobuf:"bytes,2,opt,name=SerialNumber,proto3" json:"SerialNumber,omitempty"`
+	OperState            string   `protobuf:"bytes,3,opt,name=OperState,proto3" json:"OperState,omitempty"`
+	InternalState        string   `protobuf:"bytes,4,opt,name=InternalState,proto3" json:"InternalState,omitempty"`
+	PonPortID            int32    `protobuf:"varint,5,opt,name=PonPortID,proto3" json:"PonPortID,omitempty"`
+	STag                 int32    `protobuf:"varint,6,opt,name=STag,proto3" json:"STag,omitempty"`
+	CTag                 int32    `protobuf:"varint,7,opt,name=CTag,proto3" json:"CTag,omitempty"`
+	HwAddress            string   `protobuf:"bytes,8,opt,name=HwAddress,proto3" json:"HwAddress,omitempty"`
+	PortNo               int32    `protobuf:"varint,9,opt,name=PortNo,proto3" json:"PortNo,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ONU) Reset()         { *m = ONU{} }
+func (m *ONU) String() string { return proto.CompactTextString(m) }
+func (*ONU) ProtoMessage()    {}
+func (*ONU) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{3}
+}
+
+func (m *ONU) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ONU.Unmarshal(m, b)
+}
+func (m *ONU) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ONU.Marshal(b, m, deterministic)
+}
+func (m *ONU) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ONU.Merge(m, src)
+}
+func (m *ONU) XXX_Size() int {
+	return xxx_messageInfo_ONU.Size(m)
+}
+func (m *ONU) XXX_DiscardUnknown() {
+	xxx_messageInfo_ONU.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ONU proto.InternalMessageInfo
+
+func (m *ONU) GetID() int32 {
+	if m != nil {
+		return m.ID
+	}
+	return 0
+}
+
+func (m *ONU) GetSerialNumber() string {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return ""
+}
+
+func (m *ONU) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+func (m *ONU) GetInternalState() string {
+	if m != nil {
+		return m.InternalState
+	}
+	return ""
+}
+
+func (m *ONU) GetPonPortID() int32 {
+	if m != nil {
+		return m.PonPortID
+	}
+	return 0
+}
+
+func (m *ONU) GetSTag() int32 {
+	if m != nil {
+		return m.STag
+	}
+	return 0
+}
+
+func (m *ONU) GetCTag() int32 {
+	if m != nil {
+		return m.CTag
+	}
+	return 0
+}
+
+func (m *ONU) GetHwAddress() string {
+	if m != nil {
+		return m.HwAddress
+	}
+	return ""
+}
+
+func (m *ONU) GetPortNo() int32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+type ONUs struct {
+	Items                []*ONU   `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ONUs) Reset()         { *m = ONUs{} }
+func (m *ONUs) String() string { return proto.CompactTextString(m) }
+func (*ONUs) ProtoMessage()    {}
+func (*ONUs) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{4}
+}
+
+func (m *ONUs) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ONUs.Unmarshal(m, b)
+}
+func (m *ONUs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ONUs.Marshal(b, m, deterministic)
+}
+func (m *ONUs) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ONUs.Merge(m, src)
+}
+func (m *ONUs) XXX_Size() int {
+	return xxx_messageInfo_ONUs.Size(m)
+}
+func (m *ONUs) XXX_DiscardUnknown() {
+	xxx_messageInfo_ONUs.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ONUs proto.InternalMessageInfo
+
+func (m *ONUs) GetItems() []*ONU {
+	if m != nil {
+		return m.Items
+	}
+	return nil
+}
+
+type ONURequest struct {
+	SerialNumber         string   `protobuf:"bytes,1,opt,name=SerialNumber,proto3" json:"SerialNumber,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ONURequest) Reset()         { *m = ONURequest{} }
+func (m *ONURequest) String() string { return proto.CompactTextString(m) }
+func (*ONURequest) ProtoMessage()    {}
+func (*ONURequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{5}
+}
+
+func (m *ONURequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ONURequest.Unmarshal(m, b)
+}
+func (m *ONURequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ONURequest.Marshal(b, m, deterministic)
+}
+func (m *ONURequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ONURequest.Merge(m, src)
+}
+func (m *ONURequest) XXX_Size() int {
+	return xxx_messageInfo_ONURequest.Size(m)
+}
+func (m *ONURequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ONURequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ONURequest proto.InternalMessageInfo
+
+func (m *ONURequest) GetSerialNumber() string {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return ""
+}
+
+type VersionNumber struct {
+	Version              string   `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
+	BuildTime            string   `protobuf:"bytes,2,opt,name=buildTime,proto3" json:"buildTime,omitempty"`
+	CommitHash           string   `protobuf:"bytes,3,opt,name=commitHash,proto3" json:"commitHash,omitempty"`
+	GitStatus            string   `protobuf:"bytes,4,opt,name=gitStatus,proto3" json:"gitStatus,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *VersionNumber) Reset()         { *m = VersionNumber{} }
+func (m *VersionNumber) String() string { return proto.CompactTextString(m) }
+func (*VersionNumber) ProtoMessage()    {}
+func (*VersionNumber) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{6}
+}
+
+func (m *VersionNumber) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_VersionNumber.Unmarshal(m, b)
+}
+func (m *VersionNumber) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_VersionNumber.Marshal(b, m, deterministic)
+}
+func (m *VersionNumber) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_VersionNumber.Merge(m, src)
+}
+func (m *VersionNumber) XXX_Size() int {
+	return xxx_messageInfo_VersionNumber.Size(m)
+}
+func (m *VersionNumber) XXX_DiscardUnknown() {
+	xxx_messageInfo_VersionNumber.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_VersionNumber proto.InternalMessageInfo
+
+func (m *VersionNumber) GetVersion() string {
+	if m != nil {
+		return m.Version
+	}
+	return ""
+}
+
+func (m *VersionNumber) GetBuildTime() string {
+	if m != nil {
+		return m.BuildTime
+	}
+	return ""
+}
+
+func (m *VersionNumber) GetCommitHash() string {
+	if m != nil {
+		return m.CommitHash
+	}
+	return ""
+}
+
+func (m *VersionNumber) GetGitStatus() string {
+	if m != nil {
+		return m.GitStatus
+	}
+	return ""
+}
+
+type LogLevel struct {
+	Level                string   `protobuf:"bytes,1,opt,name=level,proto3" json:"level,omitempty"`
+	Caller               bool     `protobuf:"varint,2,opt,name=caller,proto3" json:"caller,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *LogLevel) Reset()         { *m = LogLevel{} }
+func (m *LogLevel) String() string { return proto.CompactTextString(m) }
+func (*LogLevel) ProtoMessage()    {}
+func (*LogLevel) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{7}
+}
+
+func (m *LogLevel) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_LogLevel.Unmarshal(m, b)
+}
+func (m *LogLevel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_LogLevel.Marshal(b, m, deterministic)
+}
+func (m *LogLevel) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LogLevel.Merge(m, src)
+}
+func (m *LogLevel) XXX_Size() int {
+	return xxx_messageInfo_LogLevel.Size(m)
+}
+func (m *LogLevel) XXX_DiscardUnknown() {
+	xxx_messageInfo_LogLevel.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_LogLevel proto.InternalMessageInfo
+
+func (m *LogLevel) GetLevel() string {
+	if m != nil {
+		return m.Level
+	}
+	return ""
+}
+
+func (m *LogLevel) GetCaller() bool {
+	if m != nil {
+		return m.Caller
+	}
+	return false
+}
+
+type Response struct {
+	StatusCode           int32    `protobuf:"varint,1,opt,name=status_code,json=statusCode,proto3" json:"status_code,omitempty"`
+	Message              string   `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Response) Reset()         { *m = Response{} }
+func (m *Response) String() string { return proto.CompactTextString(m) }
+func (*Response) ProtoMessage()    {}
+func (*Response) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{8}
+}
+
+func (m *Response) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Response.Unmarshal(m, b)
+}
+func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Response.Marshal(b, m, deterministic)
+}
+func (m *Response) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Response.Merge(m, src)
+}
+func (m *Response) XXX_Size() int {
+	return xxx_messageInfo_Response.Size(m)
+}
+func (m *Response) XXX_DiscardUnknown() {
+	xxx_messageInfo_Response.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Response proto.InternalMessageInfo
+
+func (m *Response) GetStatusCode() int32 {
+	if m != nil {
+		return m.StatusCode
+	}
+	return 0
+}
+
+func (m *Response) GetMessage() string {
+	if m != nil {
+		return m.Message
+	}
+	return ""
+}
+
+type Empty struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Empty) Reset()         { *m = Empty{} }
+func (m *Empty) String() string { return proto.CompactTextString(m) }
+func (*Empty) ProtoMessage()    {}
+func (*Empty) Descriptor() ([]byte, []int) {
+	return fileDescriptor_ef7750073d18011b, []int{9}
+}
+
+func (m *Empty) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Empty.Unmarshal(m, b)
+}
+func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
+}
+func (m *Empty) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Empty.Merge(m, src)
+}
+func (m *Empty) XXX_Size() int {
+	return xxx_messageInfo_Empty.Size(m)
+}
+func (m *Empty) XXX_DiscardUnknown() {
+	xxx_messageInfo_Empty.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Empty proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*PONPort)(nil), "bbsim.PONPort")
+	proto.RegisterType((*NNIPort)(nil), "bbsim.NNIPort")
+	proto.RegisterType((*Olt)(nil), "bbsim.Olt")
+	proto.RegisterType((*ONU)(nil), "bbsim.ONU")
+	proto.RegisterType((*ONUs)(nil), "bbsim.ONUs")
+	proto.RegisterType((*ONURequest)(nil), "bbsim.ONURequest")
+	proto.RegisterType((*VersionNumber)(nil), "bbsim.VersionNumber")
+	proto.RegisterType((*LogLevel)(nil), "bbsim.LogLevel")
+	proto.RegisterType((*Response)(nil), "bbsim.Response")
+	proto.RegisterType((*Empty)(nil), "bbsim.Empty")
+}
+
+func init() { proto.RegisterFile("api/bbsim/bbsim.proto", fileDescriptor_ef7750073d18011b) }
+
+var fileDescriptor_ef7750073d18011b = []byte{
+	// 593 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x94, 0xd1, 0x6e, 0xda, 0x30,
+	0x14, 0x86, 0x13, 0x20, 0x04, 0x4e, 0x68, 0xa7, 0x59, 0xdd, 0x14, 0xa1, 0x6a, 0x43, 0x56, 0x35,
+	0xb1, 0x5d, 0xb4, 0x1b, 0x4c, 0xda, 0x6e, 0xd7, 0x82, 0x56, 0xa4, 0x2a, 0xa0, 0xa4, 0xec, 0x76,
+	0x0a, 0xc4, 0x82, 0x48, 0x49, 0x9c, 0xc5, 0xa6, 0x68, 0x0f, 0xb0, 0x77, 0xda, 0x8b, 0xec, 0x61,
+	0x76, 0x37, 0x39, 0x76, 0x02, 0x29, 0x9a, 0xd4, 0xed, 0xa6, 0x37, 0xc8, 0xe7, 0x3b, 0xe7, 0x3f,
+	0xb6, 0xff, 0x63, 0x02, 0xcf, 0xfc, 0x34, 0xbc, 0x58, 0x2c, 0x58, 0x18, 0xcb, 0xdf, 0xf3, 0x34,
+	0xa3, 0x9c, 0x22, 0x23, 0x0f, 0xf0, 0x07, 0x30, 0x67, 0x53, 0x67, 0x46, 0x33, 0x8e, 0x8e, 0xa1,
+	0x36, 0x19, 0xd9, 0x7a, 0x4f, 0xef, 0x1b, 0x6e, 0x6d, 0x32, 0x42, 0xa7, 0xd0, 0x9e, 0xa6, 0x24,
+	0xf3, 0xb8, 0xcf, 0x89, 0x5d, 0xeb, 0xe9, 0xfd, 0xb6, 0xbb, 0x03, 0x42, 0xe8, 0x38, 0x93, 0xff,
+	0x10, 0xfe, 0xd2, 0xa1, 0x3e, 0x8d, 0x0e, 0x55, 0x18, 0x3a, 0x1e, 0xc9, 0x42, 0x3f, 0x72, 0x36,
+	0xf1, 0x82, 0x64, 0x4a, 0x58, 0x61, 0xd5, 0xce, 0xf5, 0x7b, 0x9d, 0xd1, 0x19, 0x1c, 0x4d, 0x12,
+	0x4e, 0xb2, 0xc4, 0x8f, 0x64, 0x45, 0x23, 0xaf, 0xa8, 0x42, 0xf4, 0x06, 0x5a, 0xea, 0xe0, 0xcc,
+	0x36, 0x7a, 0xf5, 0xbe, 0x35, 0x38, 0x3e, 0x97, 0xc6, 0x28, 0xec, 0x96, 0x79, 0x51, 0xab, 0xdc,
+	0x61, 0x76, 0xb3, 0x52, 0xab, 0xb0, 0x5b, 0xe6, 0xf1, 0x6f, 0x71, 0x2f, 0x67, 0xfe, 0x68, 0xf7,
+	0x3a, 0x85, 0xf6, 0x8c, 0x26, 0xe2, 0x2c, 0x93, 0x91, 0x6d, 0xe4, 0xdb, 0xef, 0x00, 0x42, 0xd0,
+	0xf0, 0x6e, 0xfd, 0x95, 0xdd, 0xcc, 0x13, 0xf9, 0x5a, 0xb0, 0x2b, 0xc1, 0x4c, 0xc9, 0xc4, 0x5a,
+	0x74, 0xb9, 0xde, 0x7e, 0x0a, 0x82, 0x8c, 0x30, 0x66, 0xb7, 0xe4, 0x49, 0x4a, 0x80, 0x9e, 0x43,
+	0x53, 0xf4, 0x73, 0xa8, 0xdd, 0xce, 0x35, 0x2a, 0xc2, 0x7d, 0x68, 0x4c, 0x9d, 0x39, 0x43, 0x3d,
+	0x30, 0x42, 0x4e, 0x62, 0x66, 0xeb, 0xb9, 0x59, 0xa0, 0xcc, 0x9a, 0x3a, 0x73, 0x57, 0x26, 0xf0,
+	0x5b, 0x00, 0x11, 0x91, 0x6f, 0x1b, 0xc2, 0xf8, 0x81, 0x37, 0xfa, 0xa1, 0x37, 0xf8, 0x87, 0x0e,
+	0x47, 0x5f, 0x48, 0xc6, 0x42, 0x9a, 0x28, 0xb7, 0x6c, 0x30, 0xef, 0x24, 0x50, 0x82, 0x22, 0x14,
+	0xa7, 0x5f, 0x6c, 0xc2, 0x28, 0xb8, 0x0d, 0xe3, 0xf2, 0xe5, 0x95, 0x00, 0xbd, 0x00, 0x58, 0xd2,
+	0x38, 0x0e, 0xf9, 0xb5, 0xcf, 0xd6, 0xca, 0xe6, 0x3d, 0x22, 0xd4, 0xab, 0x90, 0x0b, 0x37, 0x37,
+	0x4c, 0x79, 0xbc, 0x03, 0xf8, 0x23, 0xb4, 0x6e, 0xe8, 0xea, 0x86, 0xdc, 0x91, 0x08, 0x9d, 0x80,
+	0x11, 0x89, 0x85, 0xda, 0x5f, 0x06, 0xc2, 0x9d, 0xa5, 0x1f, 0x45, 0x6a, 0xc6, 0x2d, 0x57, 0x45,
+	0x78, 0x0c, 0x2d, 0x97, 0xb0, 0x94, 0x26, 0x8c, 0xa0, 0x97, 0x60, 0xb1, 0xbc, 0xdf, 0xd7, 0x25,
+	0x0d, 0x88, 0x7a, 0x26, 0x20, 0xd1, 0x15, 0x0d, 0x88, 0xb8, 0x5c, 0x4c, 0x18, 0xf3, 0x57, 0xc5,
+	0x05, 0x8a, 0x10, 0x9b, 0x60, 0x8c, 0xe3, 0x94, 0x7f, 0x1f, 0xfc, 0xac, 0x83, 0x71, 0x79, 0xe9,
+	0x85, 0x31, 0xba, 0x00, 0x53, 0x59, 0x83, 0x3a, 0xca, 0xeb, 0xbc, 0xa4, 0x7b, 0xa2, 0xa2, 0x8a,
+	0x71, 0x58, 0x43, 0x67, 0xd0, 0xfc, 0x4c, 0xb8, 0xf8, 0xfb, 0x55, 0xeb, 0xcb, 0x49, 0x45, 0x1c,
+	0x6b, 0xe8, 0x15, 0x98, 0xa2, 0x4a, 0x4c, 0xb4, 0x5a, 0x66, 0xed, 0x06, 0xca, 0xb0, 0x86, 0x5e,
+	0xcb, 0x6e, 0xce, 0x1c, 0x3d, 0xdd, 0x9b, 0xb4, 0x9c, 0x6d, 0x77, 0x6f, 0xf8, 0x58, 0x43, 0xef,
+	0xc0, 0xf2, 0x08, 0x2f, 0x0d, 0x7c, 0xa2, 0x92, 0x05, 0xe8, 0xde, 0x07, 0x58, 0x43, 0x43, 0xb0,
+	0xbc, 0xf5, 0x86, 0x07, 0x74, 0x9b, 0xfc, 0x65, 0x8b, 0x42, 0x54, 0xb8, 0x8b, 0x35, 0x34, 0x00,
+	0x98, 0xd1, 0x2d, 0xc9, 0xe8, 0x3f, 0x68, 0xde, 0x43, 0xc7, 0x25, 0x8c, 0xfb, 0x19, 0x1f, 0xfb,
+	0x29, 0x8d, 0x1e, 0xa8, 0x1a, 0x82, 0xa5, 0x54, 0xa3, 0xf5, 0x32, 0x7d, 0x98, 0x68, 0xd1, 0xcc,
+	0x3f, 0xbe, 0xc3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x15, 0x8d, 0x8c, 0x02, 0x95, 0x05, 0x00,
+	0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// BBSimClient is the client API for BBSim service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type BBSimClient interface {
+	Version(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*VersionNumber, error)
+	GetOlt(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Olt, error)
+	GetONUs(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ONUs, error)
+	GetONU(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*ONU, error)
+	SetLogLevel(ctx context.Context, in *LogLevel, opts ...grpc.CallOption) (*LogLevel, error)
+	ShutdownONU(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error)
+	PoweronONU(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error)
+	RestartEapol(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error)
+	RestartDhcp(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error)
+}
+
+type bBSimClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewBBSimClient(cc *grpc.ClientConn) BBSimClient {
+	return &bBSimClient{cc}
+}
+
+func (c *bBSimClient) Version(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*VersionNumber, error) {
+	out := new(VersionNumber)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/Version", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) GetOlt(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Olt, error) {
+	out := new(Olt)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/GetOlt", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) GetONUs(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ONUs, error) {
+	out := new(ONUs)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/GetONUs", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) GetONU(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*ONU, error) {
+	out := new(ONU)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/GetONU", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) SetLogLevel(ctx context.Context, in *LogLevel, opts ...grpc.CallOption) (*LogLevel, error) {
+	out := new(LogLevel)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/SetLogLevel", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) ShutdownONU(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error) {
+	out := new(Response)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/ShutdownONU", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) PoweronONU(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error) {
+	out := new(Response)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/PoweronONU", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) RestartEapol(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error) {
+	out := new(Response)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/RestartEapol", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *bBSimClient) RestartDhcp(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*Response, error) {
+	out := new(Response)
+	err := c.cc.Invoke(ctx, "/bbsim.BBSim/RestartDhcp", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// BBSimServer is the server API for BBSim service.
+type BBSimServer interface {
+	Version(context.Context, *Empty) (*VersionNumber, error)
+	GetOlt(context.Context, *Empty) (*Olt, error)
+	GetONUs(context.Context, *Empty) (*ONUs, error)
+	GetONU(context.Context, *ONURequest) (*ONU, error)
+	SetLogLevel(context.Context, *LogLevel) (*LogLevel, error)
+	ShutdownONU(context.Context, *ONURequest) (*Response, error)
+	PoweronONU(context.Context, *ONURequest) (*Response, error)
+	RestartEapol(context.Context, *ONURequest) (*Response, error)
+	RestartDhcp(context.Context, *ONURequest) (*Response, error)
+}
+
+// UnimplementedBBSimServer can be embedded to have forward compatible implementations.
+type UnimplementedBBSimServer struct {
+}
+
+func (*UnimplementedBBSimServer) Version(ctx context.Context, req *Empty) (*VersionNumber, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Version not implemented")
+}
+func (*UnimplementedBBSimServer) GetOlt(ctx context.Context, req *Empty) (*Olt, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetOlt not implemented")
+}
+func (*UnimplementedBBSimServer) GetONUs(ctx context.Context, req *Empty) (*ONUs, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetONUs not implemented")
+}
+func (*UnimplementedBBSimServer) GetONU(ctx context.Context, req *ONURequest) (*ONU, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetONU not implemented")
+}
+func (*UnimplementedBBSimServer) SetLogLevel(ctx context.Context, req *LogLevel) (*LogLevel, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SetLogLevel not implemented")
+}
+func (*UnimplementedBBSimServer) ShutdownONU(ctx context.Context, req *ONURequest) (*Response, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ShutdownONU not implemented")
+}
+func (*UnimplementedBBSimServer) PoweronONU(ctx context.Context, req *ONURequest) (*Response, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PoweronONU not implemented")
+}
+func (*UnimplementedBBSimServer) RestartEapol(ctx context.Context, req *ONURequest) (*Response, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RestartEapol not implemented")
+}
+func (*UnimplementedBBSimServer) RestartDhcp(ctx context.Context, req *ONURequest) (*Response, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RestartDhcp not implemented")
+}
+
+func RegisterBBSimServer(s *grpc.Server, srv BBSimServer) {
+	s.RegisterService(&_BBSim_serviceDesc, srv)
+}
+
+func _BBSim_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).Version(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/Version",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).Version(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_GetOlt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).GetOlt(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/GetOlt",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).GetOlt(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_GetONUs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).GetONUs(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/GetONUs",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).GetONUs(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_GetONU_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).GetONU(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/GetONU",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).GetONU(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_SetLogLevel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(LogLevel)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).SetLogLevel(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/SetLogLevel",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).SetLogLevel(ctx, req.(*LogLevel))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_ShutdownONU_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).ShutdownONU(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/ShutdownONU",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).ShutdownONU(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_PoweronONU_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).PoweronONU(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/PoweronONU",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).PoweronONU(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_RestartEapol_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).RestartEapol(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/RestartEapol",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).RestartEapol(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSim_RestartDhcp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServer).RestartDhcp(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/bbsim.BBSim/RestartDhcp",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServer).RestartDhcp(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _BBSim_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "bbsim.BBSim",
+	HandlerType: (*BBSimServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "Version",
+			Handler:    _BBSim_Version_Handler,
+		},
+		{
+			MethodName: "GetOlt",
+			Handler:    _BBSim_GetOlt_Handler,
+		},
+		{
+			MethodName: "GetONUs",
+			Handler:    _BBSim_GetONUs_Handler,
+		},
+		{
+			MethodName: "GetONU",
+			Handler:    _BBSim_GetONU_Handler,
+		},
+		{
+			MethodName: "SetLogLevel",
+			Handler:    _BBSim_SetLogLevel_Handler,
+		},
+		{
+			MethodName: "ShutdownONU",
+			Handler:    _BBSim_ShutdownONU_Handler,
+		},
+		{
+			MethodName: "PoweronONU",
+			Handler:    _BBSim_PoweronONU_Handler,
+		},
+		{
+			MethodName: "RestartEapol",
+			Handler:    _BBSim_RestartEapol_Handler,
+		},
+		{
+			MethodName: "RestartDhcp",
+			Handler:    _BBSim_RestartDhcp_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "api/bbsim/bbsim.proto",
+}
diff --git a/api/bbsim/bbsim.pb.gw.go b/api/bbsim/bbsim.pb.gw.go
new file mode 100644
index 0000000..9c7f8cb
--- /dev/null
+++ b/api/bbsim/bbsim.pb.gw.go
@@ -0,0 +1,431 @@
+// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
+// source: api/bbsim/bbsim.proto
+
+/*
+Package bbsim is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package bbsim
+
+import (
+	"context"
+	"io"
+	"net/http"
+
+	"github.com/golang/protobuf/descriptor"
+	"github.com/golang/protobuf/proto"
+	"github.com/grpc-ecosystem/grpc-gateway/runtime"
+	"github.com/grpc-ecosystem/grpc-gateway/utilities"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/status"
+)
+
+// Suppress "imported and not used" errors
+var _ codes.Code
+var _ io.Reader
+var _ status.Status
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+var _ = descriptor.ForMessage
+
+func request_BBSim_Version_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.Version(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSim_Version_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.Version(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSim_GetOlt_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GetOlt(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSim_GetOlt_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GetOlt(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSim_GetOlt_1(ctx context.Context, marshaler runtime.Marshaler, client BBSimClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GetOlt(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSim_GetOlt_1(ctx context.Context, marshaler runtime.Marshaler, server BBSimServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GetOlt(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSim_GetONUs_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.GetONUs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSim_GetONUs_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.GetONUs(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSim_GetONU_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["SerialNumber"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "SerialNumber")
+	}
+
+	protoReq.SerialNumber, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "SerialNumber", err)
+	}
+
+	msg, err := client.GetONU(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSim_GetONU_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["SerialNumber"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "SerialNumber")
+	}
+
+	protoReq.SerialNumber, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "SerialNumber", err)
+	}
+
+	msg, err := server.GetONU(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+// RegisterBBSimHandlerServer registers the http handlers for service BBSim to "mux".
+// UnaryRPC     :call BBSimServer directly.
+// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
+func RegisterBBSimHandlerServer(ctx context.Context, mux *runtime.ServeMux, server BBSimServer) error {
+
+	mux.Handle("GET", pattern_BBSim_Version_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSim_Version_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_Version_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetOlt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSim_GetOlt_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetOlt_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetOlt_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSim_GetOlt_1(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetOlt_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetONUs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSim_GetONUs_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetONUs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetONU_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSim_GetONU_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetONU_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+// RegisterBBSimHandlerFromEndpoint is same as RegisterBBSimHandler but
+// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
+func RegisterBBSimHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
+	conn, err := grpc.Dial(endpoint, opts...)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if err != nil {
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+			return
+		}
+		go func() {
+			<-ctx.Done()
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+		}()
+	}()
+
+	return RegisterBBSimHandler(ctx, mux, conn)
+}
+
+// RegisterBBSimHandler registers the http handlers for service BBSim to "mux".
+// The handlers forward requests to the grpc endpoint over "conn".
+func RegisterBBSimHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+	return RegisterBBSimHandlerClient(ctx, mux, NewBBSimClient(conn))
+}
+
+// RegisterBBSimHandlerClient registers the http handlers for service BBSim
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "BBSimClient".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "BBSimClient"
+// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
+// "BBSimClient" to call the correct interceptors.
+func RegisterBBSimHandlerClient(ctx context.Context, mux *runtime.ServeMux, client BBSimClient) error {
+
+	mux.Handle("GET", pattern_BBSim_Version_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSim_Version_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_Version_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetOlt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSim_GetOlt_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetOlt_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetOlt_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSim_GetOlt_1(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetOlt_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetONUs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSim_GetONUs_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetONUs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSim_GetONU_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSim_GetONU_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSim_GetONU_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+var (
+	pattern_BBSim_Version_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "version"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSim_GetOlt_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "olt"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSim_GetOlt_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "olt", "status"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSim_GetONUs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "olt", "onus"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSim_GetONU_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "olt", "onus", "SerialNumber"}, "", runtime.AssumeColonVerbOpt(true)))
+)
+
+var (
+	forward_BBSim_Version_0 = runtime.ForwardResponseMessage
+
+	forward_BBSim_GetOlt_0 = runtime.ForwardResponseMessage
+
+	forward_BBSim_GetOlt_1 = runtime.ForwardResponseMessage
+
+	forward_BBSim_GetONUs_0 = runtime.ForwardResponseMessage
+
+	forward_BBSim_GetONU_0 = runtime.ForwardResponseMessage
+)
diff --git a/api/legacy/bbsim.pb.go b/api/legacy/bbsim.pb.go
new file mode 100644
index 0000000..060760b
--- /dev/null
+++ b/api/legacy/bbsim.pb.go
@@ -0,0 +1,1291 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: api/legacy/bbsim.proto
+
+package legacy
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	_ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
+	openolt "github.com/opencord/voltha-protos/v2/go/openolt"
+	tech_profile "github.com/opencord/voltha-protos/v2/go/tech_profile"
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+// OLT information
+//
+// Deprecated: Do not use.
+type OLTInfo struct {
+	OltId                int64    `protobuf:"varint,1,opt,name=olt_id,json=oltId,proto3" json:"olt_id,omitempty"`
+	OltSerial            string   `protobuf:"bytes,2,opt,name=olt_serial,json=oltSerial,proto3" json:"olt_serial,omitempty"`
+	OltIp                string   `protobuf:"bytes,3,opt,name=olt_ip,json=oltIp,proto3" json:"olt_ip,omitempty"`
+	OltState             string   `protobuf:"bytes,4,opt,name=olt_state,json=oltState,proto3" json:"olt_state,omitempty"`
+	OltVendor            string   `protobuf:"bytes,5,opt,name=olt_vendor,json=oltVendor,proto3" json:"olt_vendor,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OLTInfo) Reset()         { *m = OLTInfo{} }
+func (m *OLTInfo) String() string { return proto.CompactTextString(m) }
+func (*OLTInfo) ProtoMessage()    {}
+func (*OLTInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{0}
+}
+
+func (m *OLTInfo) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OLTInfo.Unmarshal(m, b)
+}
+func (m *OLTInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OLTInfo.Marshal(b, m, deterministic)
+}
+func (m *OLTInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OLTInfo.Merge(m, src)
+}
+func (m *OLTInfo) XXX_Size() int {
+	return xxx_messageInfo_OLTInfo.Size(m)
+}
+func (m *OLTInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_OLTInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OLTInfo proto.InternalMessageInfo
+
+func (m *OLTInfo) GetOltId() int64 {
+	if m != nil {
+		return m.OltId
+	}
+	return 0
+}
+
+func (m *OLTInfo) GetOltSerial() string {
+	if m != nil {
+		return m.OltSerial
+	}
+	return ""
+}
+
+func (m *OLTInfo) GetOltIp() string {
+	if m != nil {
+		return m.OltIp
+	}
+	return ""
+}
+
+func (m *OLTInfo) GetOltState() string {
+	if m != nil {
+		return m.OltState
+	}
+	return ""
+}
+
+func (m *OLTInfo) GetOltVendor() string {
+	if m != nil {
+		return m.OltVendor
+	}
+	return ""
+}
+
+// ONU information
+type ONUInfo struct {
+	OnuId     uint32 `protobuf:"varint,1,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
+	PonPortId uint32 `protobuf:"varint,2,opt,name=pon_port_id,json=ponPortId,proto3" json:"pon_port_id,omitempty"`
+	// ONU serial number
+	OnuSerial string `protobuf:"bytes,3,opt,name=onu_serial,json=onuSerial,proto3" json:"onu_serial,omitempty"`
+	// ONU oper state
+	OperState string `protobuf:"bytes,4,opt,name=oper_state,json=operState,proto3" json:"oper_state,omitempty"`
+	// ONU internal state
+	OnuState             string   `protobuf:"bytes,5,opt,name=onu_state,json=onuState,proto3" json:"onu_state,omitempty"`
+	Gemports             []uint32 `protobuf:"varint,6,rep,packed,name=gemports,proto3" json:"gemports,omitempty"`
+	Tconts               *Tconts  `protobuf:"bytes,7,opt,name=tconts,proto3" json:"tconts,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ONUInfo) Reset()         { *m = ONUInfo{} }
+func (m *ONUInfo) String() string { return proto.CompactTextString(m) }
+func (*ONUInfo) ProtoMessage()    {}
+func (*ONUInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{1}
+}
+
+func (m *ONUInfo) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ONUInfo.Unmarshal(m, b)
+}
+func (m *ONUInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ONUInfo.Marshal(b, m, deterministic)
+}
+func (m *ONUInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ONUInfo.Merge(m, src)
+}
+func (m *ONUInfo) XXX_Size() int {
+	return xxx_messageInfo_ONUInfo.Size(m)
+}
+func (m *ONUInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_ONUInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ONUInfo proto.InternalMessageInfo
+
+func (m *ONUInfo) GetOnuId() uint32 {
+	if m != nil {
+		return m.OnuId
+	}
+	return 0
+}
+
+func (m *ONUInfo) GetPonPortId() uint32 {
+	if m != nil {
+		return m.PonPortId
+	}
+	return 0
+}
+
+func (m *ONUInfo) GetOnuSerial() string {
+	if m != nil {
+		return m.OnuSerial
+	}
+	return ""
+}
+
+func (m *ONUInfo) GetOperState() string {
+	if m != nil {
+		return m.OperState
+	}
+	return ""
+}
+
+func (m *ONUInfo) GetOnuState() string {
+	if m != nil {
+		return m.OnuState
+	}
+	return ""
+}
+
+func (m *ONUInfo) GetGemports() []uint32 {
+	if m != nil {
+		return m.Gemports
+	}
+	return nil
+}
+
+func (m *ONUInfo) GetTconts() *Tconts {
+	if m != nil {
+		return m.Tconts
+	}
+	return nil
+}
+
+// Bulk ONU operations
+type ONUs struct {
+	Onus                 []*ONUInfo `protobuf:"bytes,1,rep,name=onus,proto3" json:"onus,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
+	XXX_unrecognized     []byte     `json:"-"`
+	XXX_sizecache        int32      `json:"-"`
+}
+
+func (m *ONUs) Reset()         { *m = ONUs{} }
+func (m *ONUs) String() string { return proto.CompactTextString(m) }
+func (*ONUs) ProtoMessage()    {}
+func (*ONUs) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{2}
+}
+
+func (m *ONUs) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ONUs.Unmarshal(m, b)
+}
+func (m *ONUs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ONUs.Marshal(b, m, deterministic)
+}
+func (m *ONUs) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ONUs.Merge(m, src)
+}
+func (m *ONUs) XXX_Size() int {
+	return xxx_messageInfo_ONUs.Size(m)
+}
+func (m *ONUs) XXX_DiscardUnknown() {
+	xxx_messageInfo_ONUs.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ONUs proto.InternalMessageInfo
+
+func (m *ONUs) GetOnus() []*ONUInfo {
+	if m != nil {
+		return m.Onus
+	}
+	return nil
+}
+
+type ONURequest struct {
+	Onu                  *ONUInfo `protobuf:"bytes,1,opt,name=onu,proto3" json:"onu,omitempty"`
+	OnusBatch            *ONUs    `protobuf:"bytes,2,opt,name=onus_batch,json=onusBatch,proto3" json:"onus_batch,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ONURequest) Reset()         { *m = ONURequest{} }
+func (m *ONURequest) String() string { return proto.CompactTextString(m) }
+func (*ONURequest) ProtoMessage()    {}
+func (*ONURequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{3}
+}
+
+func (m *ONURequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ONURequest.Unmarshal(m, b)
+}
+func (m *ONURequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ONURequest.Marshal(b, m, deterministic)
+}
+func (m *ONURequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ONURequest.Merge(m, src)
+}
+func (m *ONURequest) XXX_Size() int {
+	return xxx_messageInfo_ONURequest.Size(m)
+}
+func (m *ONURequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ONURequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ONURequest proto.InternalMessageInfo
+
+func (m *ONURequest) GetOnu() *ONUInfo {
+	if m != nil {
+		return m.Onu
+	}
+	return nil
+}
+
+func (m *ONURequest) GetOnusBatch() *ONUs {
+	if m != nil {
+		return m.OnusBatch
+	}
+	return nil
+}
+
+// Port information
+type PortInfo struct {
+	PortType             string   `protobuf:"bytes,1,opt,name=port_type,json=portType,proto3" json:"port_type,omitempty"`
+	PortId               uint32   `protobuf:"varint,2,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"`
+	PonPortMaxOnus       uint32   `protobuf:"varint,3,opt,name=pon_port_max_onus,json=ponPortMaxOnus,proto3" json:"pon_port_max_onus,omitempty"`
+	PonPortActiveOnus    uint32   `protobuf:"varint,4,opt,name=pon_port_active_onus,json=ponPortActiveOnus,proto3" json:"pon_port_active_onus,omitempty"`
+	PortState            string   `protobuf:"bytes,5,opt,name=port_state,json=portState,proto3" json:"port_state,omitempty"`
+	AlarmState           string   `protobuf:"bytes,6,opt,name=alarm_state,json=alarmState,proto3" json:"alarm_state,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *PortInfo) Reset()         { *m = PortInfo{} }
+func (m *PortInfo) String() string { return proto.CompactTextString(m) }
+func (*PortInfo) ProtoMessage()    {}
+func (*PortInfo) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{4}
+}
+
+func (m *PortInfo) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_PortInfo.Unmarshal(m, b)
+}
+func (m *PortInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_PortInfo.Marshal(b, m, deterministic)
+}
+func (m *PortInfo) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PortInfo.Merge(m, src)
+}
+func (m *PortInfo) XXX_Size() int {
+	return xxx_messageInfo_PortInfo.Size(m)
+}
+func (m *PortInfo) XXX_DiscardUnknown() {
+	xxx_messageInfo_PortInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PortInfo proto.InternalMessageInfo
+
+func (m *PortInfo) GetPortType() string {
+	if m != nil {
+		return m.PortType
+	}
+	return ""
+}
+
+func (m *PortInfo) GetPortId() uint32 {
+	if m != nil {
+		return m.PortId
+	}
+	return 0
+}
+
+func (m *PortInfo) GetPonPortMaxOnus() uint32 {
+	if m != nil {
+		return m.PonPortMaxOnus
+	}
+	return 0
+}
+
+func (m *PortInfo) GetPonPortActiveOnus() uint32 {
+	if m != nil {
+		return m.PonPortActiveOnus
+	}
+	return 0
+}
+
+func (m *PortInfo) GetPortState() string {
+	if m != nil {
+		return m.PortState
+	}
+	return ""
+}
+
+func (m *PortInfo) GetAlarmState() string {
+	if m != nil {
+		return m.AlarmState
+	}
+	return ""
+}
+
+// Bulk port information
+type Ports struct {
+	Ports                []*PortInfo `protobuf:"bytes,1,rep,name=ports,proto3" json:"ports,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
+	XXX_unrecognized     []byte      `json:"-"`
+	XXX_sizecache        int32       `json:"-"`
+}
+
+func (m *Ports) Reset()         { *m = Ports{} }
+func (m *Ports) String() string { return proto.CompactTextString(m) }
+func (*Ports) ProtoMessage()    {}
+func (*Ports) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{5}
+}
+
+func (m *Ports) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Ports.Unmarshal(m, b)
+}
+func (m *Ports) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Ports.Marshal(b, m, deterministic)
+}
+func (m *Ports) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Ports.Merge(m, src)
+}
+func (m *Ports) XXX_Size() int {
+	return xxx_messageInfo_Ports.Size(m)
+}
+func (m *Ports) XXX_DiscardUnknown() {
+	xxx_messageInfo_Ports.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Ports proto.InternalMessageInfo
+
+func (m *Ports) GetPorts() []*PortInfo {
+	if m != nil {
+		return m.Ports
+	}
+	return nil
+}
+
+// BBSim status
+type OLTStatusResponse struct {
+	Olt                  *OLTInfo    `protobuf:"bytes,1,opt,name=olt,proto3" json:"olt,omitempty"`
+	Ports                []*PortInfo `protobuf:"bytes,2,rep,name=ports,proto3" json:"ports,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
+	XXX_unrecognized     []byte      `json:"-"`
+	XXX_sizecache        int32       `json:"-"`
+}
+
+func (m *OLTStatusResponse) Reset()         { *m = OLTStatusResponse{} }
+func (m *OLTStatusResponse) String() string { return proto.CompactTextString(m) }
+func (*OLTStatusResponse) ProtoMessage()    {}
+func (*OLTStatusResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{6}
+}
+
+func (m *OLTStatusResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OLTStatusResponse.Unmarshal(m, b)
+}
+func (m *OLTStatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OLTStatusResponse.Marshal(b, m, deterministic)
+}
+func (m *OLTStatusResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OLTStatusResponse.Merge(m, src)
+}
+func (m *OLTStatusResponse) XXX_Size() int {
+	return xxx_messageInfo_OLTStatusResponse.Size(m)
+}
+func (m *OLTStatusResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_OLTStatusResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OLTStatusResponse proto.InternalMessageInfo
+
+func (m *OLTStatusResponse) GetOlt() *OLTInfo {
+	if m != nil {
+		return m.Olt
+	}
+	return nil
+}
+
+func (m *OLTStatusResponse) GetPorts() []*PortInfo {
+	if m != nil {
+		return m.Ports
+	}
+	return nil
+}
+
+// BBSim response message
+type BBSimResponse struct {
+	StatusMsg            string   `protobuf:"bytes,1,opt,name=status_msg,json=statusMsg,proto3" json:"status_msg,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *BBSimResponse) Reset()         { *m = BBSimResponse{} }
+func (m *BBSimResponse) String() string { return proto.CompactTextString(m) }
+func (*BBSimResponse) ProtoMessage()    {}
+func (*BBSimResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{7}
+}
+
+func (m *BBSimResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_BBSimResponse.Unmarshal(m, b)
+}
+func (m *BBSimResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_BBSimResponse.Marshal(b, m, deterministic)
+}
+func (m *BBSimResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_BBSimResponse.Merge(m, src)
+}
+func (m *BBSimResponse) XXX_Size() int {
+	return xxx_messageInfo_BBSimResponse.Size(m)
+}
+func (m *BBSimResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_BBSimResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BBSimResponse proto.InternalMessageInfo
+
+func (m *BBSimResponse) GetStatusMsg() string {
+	if m != nil {
+		return m.StatusMsg
+	}
+	return ""
+}
+
+// ONU alarm request
+type ONUAlarmRequest struct {
+	// ONU serial number
+	OnuSerial string `protobuf:"bytes,1,opt,name=onu_serial,json=onuSerial,proto3" json:"onu_serial,omitempty"`
+	// Alarm types are:
+	//   "signaldegrade"
+	//   "lossofomcichannel"
+	//   "lossofploam"
+	AlarmType string `protobuf:"bytes,2,opt,name=alarm_type,json=alarmType,proto3" json:"alarm_type,omitempty"`
+	// "on"/"off" indicates raised or cleared alarm
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ONUAlarmRequest) Reset()         { *m = ONUAlarmRequest{} }
+func (m *ONUAlarmRequest) String() string { return proto.CompactTextString(m) }
+func (*ONUAlarmRequest) ProtoMessage()    {}
+func (*ONUAlarmRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{8}
+}
+
+func (m *ONUAlarmRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ONUAlarmRequest.Unmarshal(m, b)
+}
+func (m *ONUAlarmRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ONUAlarmRequest.Marshal(b, m, deterministic)
+}
+func (m *ONUAlarmRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ONUAlarmRequest.Merge(m, src)
+}
+func (m *ONUAlarmRequest) XXX_Size() int {
+	return xxx_messageInfo_ONUAlarmRequest.Size(m)
+}
+func (m *ONUAlarmRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ONUAlarmRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ONUAlarmRequest proto.InternalMessageInfo
+
+func (m *ONUAlarmRequest) GetOnuSerial() string {
+	if m != nil {
+		return m.OnuSerial
+	}
+	return ""
+}
+
+func (m *ONUAlarmRequest) GetAlarmType() string {
+	if m != nil {
+		return m.AlarmType
+	}
+	return ""
+}
+
+func (m *ONUAlarmRequest) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+// OLT alarm request
+type OLTAlarmRequest struct {
+	PortId               uint32   `protobuf:"varint,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"`
+	PortType             string   `protobuf:"bytes,2,opt,name=port_type,json=portType,proto3" json:"port_type,omitempty"`
+	Status               string   `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *OLTAlarmRequest) Reset()         { *m = OLTAlarmRequest{} }
+func (m *OLTAlarmRequest) String() string { return proto.CompactTextString(m) }
+func (*OLTAlarmRequest) ProtoMessage()    {}
+func (*OLTAlarmRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{9}
+}
+
+func (m *OLTAlarmRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_OLTAlarmRequest.Unmarshal(m, b)
+}
+func (m *OLTAlarmRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_OLTAlarmRequest.Marshal(b, m, deterministic)
+}
+func (m *OLTAlarmRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_OLTAlarmRequest.Merge(m, src)
+}
+func (m *OLTAlarmRequest) XXX_Size() int {
+	return xxx_messageInfo_OLTAlarmRequest.Size(m)
+}
+func (m *OLTAlarmRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_OLTAlarmRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_OLTAlarmRequest proto.InternalMessageInfo
+
+func (m *OLTAlarmRequest) GetPortId() uint32 {
+	if m != nil {
+		return m.PortId
+	}
+	return 0
+}
+
+func (m *OLTAlarmRequest) GetPortType() string {
+	if m != nil {
+		return m.PortType
+	}
+	return ""
+}
+
+func (m *OLTAlarmRequest) GetStatus() string {
+	if m != nil {
+		return m.Status
+	}
+	return ""
+}
+
+// Device action
+type DeviceAction struct {
+	DeviceType           string   `protobuf:"bytes,1,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"`
+	SerialNumber         string   `protobuf:"bytes,2,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"`
+	Action               string   `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *DeviceAction) Reset()         { *m = DeviceAction{} }
+func (m *DeviceAction) String() string { return proto.CompactTextString(m) }
+func (*DeviceAction) ProtoMessage()    {}
+func (*DeviceAction) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{10}
+}
+
+func (m *DeviceAction) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceAction.Unmarshal(m, b)
+}
+func (m *DeviceAction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceAction.Marshal(b, m, deterministic)
+}
+func (m *DeviceAction) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceAction.Merge(m, src)
+}
+func (m *DeviceAction) XXX_Size() int {
+	return xxx_messageInfo_DeviceAction.Size(m)
+}
+func (m *DeviceAction) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceAction.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceAction proto.InternalMessageInfo
+
+func (m *DeviceAction) GetDeviceType() string {
+	if m != nil {
+		return m.DeviceType
+	}
+	return ""
+}
+
+func (m *DeviceAction) GetSerialNumber() string {
+	if m != nil {
+		return m.SerialNumber
+	}
+	return ""
+}
+
+func (m *DeviceAction) GetAction() string {
+	if m != nil {
+		return m.Action
+	}
+	return ""
+}
+
+type Tconts struct {
+	UniId                uint32                           `protobuf:"fixed32,4,opt,name=uni_id,json=uniId,proto3" json:"uni_id,omitempty"`
+	PortNo               uint32                           `protobuf:"fixed32,5,opt,name=port_no,json=portNo,proto3" json:"port_no,omitempty"`
+	Tconts               []*tech_profile.TrafficScheduler `protobuf:"bytes,3,rep,name=tconts,proto3" json:"tconts,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                         `json:"-"`
+	XXX_unrecognized     []byte                           `json:"-"`
+	XXX_sizecache        int32                            `json:"-"`
+}
+
+func (m *Tconts) Reset()         { *m = Tconts{} }
+func (m *Tconts) String() string { return proto.CompactTextString(m) }
+func (*Tconts) ProtoMessage()    {}
+func (*Tconts) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{11}
+}
+
+func (m *Tconts) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Tconts.Unmarshal(m, b)
+}
+func (m *Tconts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Tconts.Marshal(b, m, deterministic)
+}
+func (m *Tconts) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Tconts.Merge(m, src)
+}
+func (m *Tconts) XXX_Size() int {
+	return xxx_messageInfo_Tconts.Size(m)
+}
+func (m *Tconts) XXX_DiscardUnknown() {
+	xxx_messageInfo_Tconts.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Tconts proto.InternalMessageInfo
+
+func (m *Tconts) GetUniId() uint32 {
+	if m != nil {
+		return m.UniId
+	}
+	return 0
+}
+
+func (m *Tconts) GetPortNo() uint32 {
+	if m != nil {
+		return m.PortNo
+	}
+	return 0
+}
+
+func (m *Tconts) GetTconts() []*tech_profile.TrafficScheduler {
+	if m != nil {
+		return m.Tconts
+	}
+	return nil
+}
+
+type Flows struct {
+	Flows                []*openolt.Flow `protobuf:"bytes,1,rep,name=flows,proto3" json:"flows,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
+	XXX_unrecognized     []byte          `json:"-"`
+	XXX_sizecache        int32           `json:"-"`
+}
+
+func (m *Flows) Reset()         { *m = Flows{} }
+func (m *Flows) String() string { return proto.CompactTextString(m) }
+func (*Flows) ProtoMessage()    {}
+func (*Flows) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{12}
+}
+
+func (m *Flows) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Flows.Unmarshal(m, b)
+}
+func (m *Flows) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Flows.Marshal(b, m, deterministic)
+}
+func (m *Flows) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Flows.Merge(m, src)
+}
+func (m *Flows) XXX_Size() int {
+	return xxx_messageInfo_Flows.Size(m)
+}
+func (m *Flows) XXX_DiscardUnknown() {
+	xxx_messageInfo_Flows.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Flows proto.InternalMessageInfo
+
+func (m *Flows) GetFlows() []*openolt.Flow {
+	if m != nil {
+		return m.Flows
+	}
+	return nil
+}
+
+type Empty struct {
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Empty) Reset()         { *m = Empty{} }
+func (m *Empty) String() string { return proto.CompactTextString(m) }
+func (*Empty) ProtoMessage()    {}
+func (*Empty) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6ea2bed57327b60e, []int{13}
+}
+
+func (m *Empty) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Empty.Unmarshal(m, b)
+}
+func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
+}
+func (m *Empty) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Empty.Merge(m, src)
+}
+func (m *Empty) XXX_Size() int {
+	return xxx_messageInfo_Empty.Size(m)
+}
+func (m *Empty) XXX_DiscardUnknown() {
+	xxx_messageInfo_Empty.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Empty proto.InternalMessageInfo
+
+func init() {
+	proto.RegisterType((*OLTInfo)(nil), "legacy.OLTInfo")
+	proto.RegisterType((*ONUInfo)(nil), "legacy.ONUInfo")
+	proto.RegisterType((*ONUs)(nil), "legacy.ONUs")
+	proto.RegisterType((*ONURequest)(nil), "legacy.ONURequest")
+	proto.RegisterType((*PortInfo)(nil), "legacy.PortInfo")
+	proto.RegisterType((*Ports)(nil), "legacy.Ports")
+	proto.RegisterType((*OLTStatusResponse)(nil), "legacy.OLTStatusResponse")
+	proto.RegisterType((*BBSimResponse)(nil), "legacy.BBSimResponse")
+	proto.RegisterType((*ONUAlarmRequest)(nil), "legacy.ONUAlarmRequest")
+	proto.RegisterType((*OLTAlarmRequest)(nil), "legacy.OLTAlarmRequest")
+	proto.RegisterType((*DeviceAction)(nil), "legacy.DeviceAction")
+	proto.RegisterType((*Tconts)(nil), "legacy.Tconts")
+	proto.RegisterType((*Flows)(nil), "legacy.Flows")
+	proto.RegisterType((*Empty)(nil), "legacy.Empty")
+}
+
+func init() { proto.RegisterFile("api/legacy/bbsim.proto", fileDescriptor_6ea2bed57327b60e) }
+
+var fileDescriptor_6ea2bed57327b60e = []byte{
+	// 1326 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4d, 0x6f, 0x1b, 0x55,
+	0x17, 0xd6, 0xd8, 0xb1, 0x1d, 0x9f, 0xc4, 0x6d, 0x7a, 0xfb, 0xe5, 0x37, 0x79, 0xd3, 0x4e, 0xa7,
+	0x55, 0x08, 0x69, 0xeb, 0x69, 0xdd, 0x2f, 0x08, 0xab, 0x44, 0x85, 0x2a, 0x52, 0x6b, 0x47, 0x93,
+	0x84, 0x85, 0xa9, 0xb0, 0x26, 0xf6, 0xb5, 0x3d, 0x68, 0x7c, 0xef, 0x30, 0xf7, 0x4e, 0xda, 0xc8,
+	0xf2, 0x06, 0x01, 0xea, 0x02, 0x16, 0x80, 0x54, 0x21, 0x96, 0xec, 0xf8, 0x15, 0xec, 0xf8, 0x03,
+	0x6c, 0x91, 0xba, 0x80, 0x1f, 0x82, 0xee, 0xb9, 0x33, 0xce, 0x4c, 0x3e, 0x20, 0x65, 0x15, 0xdf,
+	0x73, 0xce, 0xbd, 0xe7, 0x79, 0xce, 0xc7, 0x93, 0x81, 0x4b, 0x6e, 0xe0, 0xd9, 0x3e, 0xed, 0xbb,
+	0x9d, 0x7d, 0x7b, 0x77, 0x57, 0x78, 0xc3, 0x5a, 0x10, 0x72, 0xc9, 0x49, 0x51, 0xdb, 0xe6, 0xff,
+	0xdf, 0xe7, 0xbc, 0xef, 0x53, 0x5b, 0x85, 0xb9, 0x8c, 0x71, 0xe9, 0x4a, 0x8f, 0x33, 0xa1, 0xa3,
+	0xe6, 0x6f, 0xe1, 0x9f, 0xce, 0xed, 0x3e, 0x65, 0xb7, 0xc5, 0x0b, 0xb7, 0xdf, 0xa7, 0xa1, 0xcd,
+	0x03, 0x8c, 0x38, 0x26, 0x7a, 0x61, 0x8f, 0xfb, 0x72, 0xe0, 0xb6, 0xf1, 0x24, 0x6c, 0x1e, 0x50,
+	0xc6, 0x7d, 0x19, 0x3b, 0xcd, 0xac, 0x53, 0xd2, 0xce, 0x40, 0xfd, 0xee, 0x79, 0x3e, 0xd5, 0x11,
+	0xd6, 0x6b, 0x03, 0x4a, 0xcd, 0xa7, 0xdb, 0x1b, 0xac, 0xc7, 0xc9, 0x45, 0x28, 0x72, 0x5f, 0xb6,
+	0xbd, 0x6e, 0xd5, 0x30, 0x8d, 0xe5, 0xbc, 0x53, 0xe0, 0xbe, 0xdc, 0xe8, 0x92, 0x45, 0x00, 0x65,
+	0x16, 0x34, 0xf4, 0x5c, 0xbf, 0x9a, 0x33, 0x8d, 0xe5, 0xb2, 0x53, 0xe6, 0xbe, 0xdc, 0x42, 0xc3,
+	0xe4, 0x56, 0x50, 0xcd, 0xa3, 0x0b, 0x6f, 0x05, 0x64, 0x01, 0xca, 0x78, 0x4b, 0xba, 0x92, 0x56,
+	0xa7, 0xd0, 0x33, 0xad, 0x2e, 0xa9, 0x73, 0xf2, 0xe4, 0x1e, 0x65, 0x5d, 0x1e, 0x56, 0x0b, 0x93,
+	0x27, 0x3f, 0x46, 0xc3, 0x6a, 0xae, 0x6a, 0x58, 0x6f, 0x14, 0xb0, 0xc6, 0xce, 0x04, 0x18, 0x8b,
+	0x12, 0x60, 0x15, 0xa7, 0xc0, 0x59, 0xb4, 0xd1, 0x25, 0x57, 0x60, 0x26, 0xe0, 0xac, 0x1d, 0xf0,
+	0x10, 0x41, 0xe7, 0xd0, 0x57, 0x0e, 0x38, 0xdb, 0xe4, 0x61, 0x02, 0x9c, 0x45, 0x09, 0xf0, 0x7c,
+	0x9c, 0x85, 0x45, 0x31, 0x70, 0xe5, 0x0e, 0x68, 0x98, 0x81, 0x58, 0x56, 0x16, 0x8d, 0x51, 0x11,
+	0x50, 0xb7, 0xd1, 0x5b, 0x88, 0x09, 0xb0, 0x48, 0x3b, 0xe7, 0x61, 0xba, 0x4f, 0x87, 0x2a, 0xb3,
+	0xa8, 0x16, 0xcd, 0xfc, 0x72, 0xc5, 0x99, 0x9c, 0xc9, 0x12, 0x14, 0x65, 0x87, 0x33, 0x29, 0xaa,
+	0x25, 0xd3, 0x58, 0x9e, 0xa9, 0x9f, 0xa9, 0xe9, 0xb6, 0xd7, 0xb6, 0xd1, 0xea, 0xc4, 0x5e, 0xeb,
+	0x26, 0x4c, 0x35, 0x1b, 0x3b, 0x82, 0x5c, 0x87, 0x29, 0xce, 0x22, 0x51, 0x35, 0xcc, 0xfc, 0xf2,
+	0x4c, 0xfd, 0x6c, 0x12, 0x1d, 0x93, 0x77, 0xd0, 0x69, 0x3d, 0x07, 0x68, 0x36, 0x76, 0x1c, 0xfa,
+	0x79, 0x44, 0x85, 0x24, 0xd7, 0x20, 0xcf, 0x59, 0x84, 0xd5, 0x38, 0xe6, 0x86, 0xf2, 0x91, 0x9b,
+	0x48, 0x5e, 0xb4, 0x77, 0x5d, 0xd9, 0x19, 0x60, 0x6d, 0x66, 0xea, 0xb3, 0xa9, 0x48, 0x81, 0xa5,
+	0x10, 0xeb, 0xca, 0x6d, 0xfd, 0x61, 0xc0, 0x34, 0x16, 0x4d, 0x55, 0x7b, 0x01, 0xca, 0x58, 0x52,
+	0xb9, 0x1f, 0x50, 0x4c, 0x51, 0x76, 0xa6, 0x95, 0x61, 0x7b, 0x3f, 0xa0, 0xe4, 0x32, 0x94, 0xb2,
+	0xf5, 0x2e, 0x06, 0xba, 0xd8, 0xef, 0xc2, 0xb9, 0x49, 0x33, 0x86, 0xee, 0xcb, 0x36, 0x52, 0xca,
+	0x63, 0xc8, 0x99, 0xb8, 0x25, 0xcf, 0xdc, 0x97, 0x4d, 0x16, 0x09, 0x62, 0xc3, 0x85, 0x49, 0xa8,
+	0xdb, 0x91, 0xde, 0x1e, 0xd5, 0xd1, 0x53, 0x18, 0x7d, 0x2e, 0x8e, 0x5e, 0x43, 0x0f, 0x5e, 0x58,
+	0x04, 0xc0, 0xe0, 0x74, 0x2f, 0x10, 0xa3, 0x6e, 0xc6, 0x55, 0x98, 0x71, 0x7d, 0x37, 0x1c, 0xc6,
+	0xfe, 0x22, 0xfa, 0x01, 0x4d, 0x18, 0x60, 0xd9, 0x50, 0xd8, 0x8c, 0x5b, 0x53, 0xd0, 0x3d, 0xd3,
+	0xb5, 0x9e, 0x4b, 0xea, 0x91, 0x70, 0x77, 0xb4, 0xdb, 0xfa, 0x14, 0xce, 0x35, 0x9f, 0x6e, 0xab,
+	0xcb, 0x91, 0x70, 0xa8, 0x08, 0x38, 0x13, 0x14, 0x8b, 0xee, 0xcb, 0x23, 0x45, 0xd7, 0xcb, 0xe3,
+	0x28, 0xdf, 0xc1, 0xfb, 0xb9, 0x7f, 0x7e, 0xbf, 0x06, 0x95, 0xf5, 0xf5, 0x2d, 0x6f, 0x38, 0x79,
+	0x7b, 0x11, 0x40, 0x60, 0xb6, 0xf6, 0x50, 0xf4, 0xe3, 0xa2, 0x97, 0xb5, 0xe5, 0x99, 0xe8, 0x5b,
+	0x7d, 0x38, 0xdb, 0x6c, 0xec, 0xac, 0x29, 0x46, 0xc9, 0x08, 0x64, 0x87, 0xdb, 0x38, 0x66, 0xb8,
+	0x75, 0x4d, 0xb0, 0x8b, 0xf1, 0xd2, 0xa2, 0x05, 0xdb, 0x78, 0x09, 0x8a, 0xfa, 0xf5, 0x78, 0x2d,
+	0xe2, 0x93, 0xd5, 0x86, 0xb3, 0xcd, 0xa7, 0xdb, 0x99, 0x44, 0xa9, 0x8e, 0x1b, 0x99, 0x8e, 0x67,
+	0xe6, 0x24, 0x77, 0x68, 0x4e, 0x4e, 0x4a, 0xe0, 0xc3, 0xec, 0x63, 0xba, 0xe7, 0x75, 0xa8, 0x6a,
+	0x2f, 0x67, 0xaa, 0x77, 0x5d, 0x3c, 0xa7, 0xc7, 0x0d, 0xb4, 0x09, 0x1f, 0xba, 0x0e, 0x15, 0xcd,
+	0xb1, 0xcd, 0xa2, 0xe1, 0x2e, 0x0d, 0xe3, 0x4c, 0xb3, 0xda, 0xd8, 0x40, 0x9b, 0xca, 0xe6, 0xe2,
+	0x7b, 0x49, 0x36, 0x7d, 0xb2, 0x02, 0x28, 0xea, 0xa5, 0x53, 0x12, 0x12, 0x31, 0x4f, 0x91, 0x50,
+	0x53, 0x56, 0x72, 0x0a, 0x11, 0xf3, 0x36, 0xba, 0x13, 0x72, 0x8c, 0xe3, 0x58, 0x95, 0x34, 0xb9,
+	0x06, 0x27, 0x0f, 0x27, 0x4b, 0x9c, 0xc7, 0x56, 0x5e, 0xa9, 0x65, 0xc4, 0x73, 0x3b, 0x74, 0x7b,
+	0x3d, 0xaf, 0xb3, 0xd5, 0x19, 0xd0, 0x6e, 0xe4, 0xd3, 0x70, 0xb2, 0xd4, 0xb7, 0xa0, 0xf0, 0x91,
+	0xcf, 0x5f, 0xa8, 0xad, 0x2e, 0xf4, 0xd4, 0x8f, 0x78, 0xd4, 0x2a, 0xb5, 0x44, 0x99, 0x95, 0xdb,
+	0xd1, 0x3e, 0xab, 0x04, 0x85, 0x0f, 0x87, 0x81, 0xdc, 0xaf, 0xff, 0x09, 0x30, 0x8b, 0x13, 0xb1,
+	0x45, 0x43, 0x45, 0x9d, 0x7c, 0x02, 0xe5, 0xc9, 0x04, 0x92, 0x4a, 0x32, 0x47, 0x18, 0x3c, 0xff,
+	0xbf, 0xd4, 0xec, 0x65, 0x67, 0xd4, 0xba, 0xf1, 0xc5, 0xef, 0x7f, 0xfd, 0x90, 0x5b, 0x20, 0x25,
+	0x7b, 0xef, 0x8e, 0xcd, 0x7d, 0xd9, 0x9a, 0x23, 0x67, 0xe2, 0x9f, 0xb6, 0xee, 0xc0, 0xab, 0x9c,
+	0x41, 0xba, 0x00, 0x9b, 0xf1, 0xf6, 0x44, 0x82, 0x1c, 0x99, 0xd2, 0xf9, 0x4a, 0xda, 0x22, 0xac,
+	0x07, 0xf8, 0xe8, 0x2d, 0xb2, 0x92, 0xbc, 0x84, 0x43, 0x6c, 0x8f, 0x26, 0xdd, 0x1f, 0xc7, 0xbf,
+	0xbd, 0xee, 0x38, 0x95, 0xe5, 0x37, 0x03, 0xca, 0xcd, 0xc6, 0x4e, 0x9c, 0x85, 0xa4, 0xb4, 0x27,
+	0x1e, 0xad, 0xf9, 0x8c, 0x1e, 0x59, 0xaf, 0x0d, 0xcc, 0xf3, 0x8d, 0x41, 0x66, 0x93, 0x44, 0x4a,
+	0x16, 0x5a, 0x57, 0xc9, 0x62, 0xfa, 0x6c, 0x8f, 0x38, 0x8b, 0x6a, 0x07, 0xb3, 0x3f, 0x6e, 0xdd,
+	0x23, 0x77, 0x0f, 0x21, 0x53, 0x11, 0xa9, 0x7f, 0x0d, 0xe3, 0x43, 0x17, 0xbd, 0xee, 0xb8, 0xb5,
+	0x44, 0x6e, 0x9c, 0xe6, 0x92, 0x22, 0xf2, 0xab, 0x01, 0x33, 0x6a, 0xfd, 0x94, 0x20, 0x29, 0xbd,
+	0x39, 0x8e, 0xca, 0xc5, 0xc4, 0x96, 0xd9, 0x6b, 0xeb, 0x4b, 0xcd, 0x69, 0x64, 0x65, 0x28, 0xad,
+	0xa6, 0xa4, 0xb9, 0xb5, 0x64, 0x9d, 0x0a, 0x48, 0xeb, 0x91, 0xf5, 0xe0, 0xed, 0x58, 0xc6, 0xe5,
+	0x51, 0x0c, 0xde, 0x18, 0x50, 0x69, 0x36, 0x76, 0x1e, 0x53, 0xf7, 0x3f, 0x70, 0xf8, 0x59, 0x73,
+	0xf8, 0xd1, 0x58, 0x39, 0x99, 0xc4, 0xd5, 0x95, 0x7f, 0xe9, 0xd1, 0xd2, 0xca, 0xe9, 0x58, 0xde,
+	0x5b, 0x79, 0xfb, 0x5e, 0x2a, 0x86, 0x5f, 0x19, 0x30, 0xf7, 0x84, 0x32, 0x1a, 0xba, 0x92, 0x26,
+	0x52, 0x49, 0x2e, 0xa7, 0x48, 0xa6, 0x35, 0xed, 0x24, 0xa6, 0x6b, 0x48, 0xf4, 0x3d, 0xeb, 0xe1,
+	0x11, 0x2e, 0x09, 0x0f, 0x1b, 0x25, 0x54, 0xd8, 0xa3, 0x03, 0x71, 0x1d, 0xdb, 0x23, 0x3d, 0xf3,
+	0x88, 0xe3, 0xeb, 0x34, 0x8e, 0x58, 0x49, 0x53, 0x38, 0xb2, 0xda, 0x7a, 0x12, 0x8e, 0x75, 0xc4,
+	0xf1, 0xbe, 0xf5, 0xe8, 0x34, 0x0b, 0x17, 0x23, 0xf2, 0xb9, 0xc8, 0x00, 0xf9, 0xc5, 0x80, 0xf3,
+	0x9b, 0x34, 0xec, 0xf1, 0x70, 0x98, 0x11, 0xdc, 0x0b, 0x49, 0xca, 0xb4, 0xf5, 0x24, 0x20, 0x14,
+	0x81, 0x3c, 0xaf, 0x5f, 0x53, 0x40, 0x46, 0x29, 0xa1, 0x1e, 0xdb, 0x5a, 0x61, 0xed, 0x91, 0xfe,
+	0x3b, 0x6e, 0x3d, 0xaa, 0x4f, 0xc6, 0x33, 0x1b, 0x38, 0xca, 0xc8, 0xf7, 0x91, 0x8b, 0x0a, 0x6b,
+	0x0f, 0xa6, 0x9f, 0x50, 0xa9, 0x75, 0xf3, 0xf0, 0xd7, 0xcc, 0x81, 0x18, 0xa1, 0xdf, 0x5a, 0x45,
+	0x48, 0x77, 0x49, 0x25, 0xc9, 0x86, 0x4a, 0xda, 0x32, 0xc9, 0x95, 0x54, 0xd3, 0xb2, 0x3d, 0xc3,
+	0x88, 0x57, 0x39, 0x63, 0xfd, 0x3b, 0xe3, 0xfb, 0xb5, 0x6f, 0x0d, 0xf2, 0x0e, 0x94, 0x91, 0xa6,
+	0xb9, 0xb6, 0xb9, 0x61, 0x5d, 0x24, 0xe7, 0x07, 0x52, 0x06, 0xab, 0x36, 0x7e, 0x3a, 0x77, 0x78,
+	0xd8, 0xad, 0xf1, 0xb0, 0x5f, 0xcf, 0xdf, 0xad, 0xdd, 0x59, 0x31, 0x8c, 0xfa, 0x9c, 0x1b, 0x04,
+	0xbe, 0xd7, 0xc1, 0x4f, 0x6e, 0xfb, 0x33, 0xc1, 0xd9, 0xea, 0x11, 0x8b, 0xf3, 0x01, 0xe4, 0xef,
+	0xdf, 0xb9, 0x4f, 0xee, 0xc3, 0x8a, 0x43, 0x65, 0x14, 0x32, 0xda, 0x35, 0x5f, 0x0c, 0x28, 0x33,
+	0xe5, 0x80, 0x9a, 0x21, 0x15, 0x3c, 0x0a, 0x3b, 0xd4, 0xec, 0x72, 0x2a, 0x4c, 0xc6, 0xa5, 0x49,
+	0x5f, 0x7a, 0x42, 0xd6, 0x48, 0x11, 0xa6, 0x7e, 0xca, 0x19, 0xa5, 0xdd, 0x22, 0x7e, 0x87, 0xdf,
+	0xfb, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x5f, 0xb3, 0x49, 0x58, 0x34, 0x0c, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// BBSimServiceClient is the client API for BBSimService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type BBSimServiceClient interface {
+	// Get current status of OLT
+	OLTStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*OLTStatusResponse, error)
+	// Get status of a PON/NNI port
+	PortStatus(ctx context.Context, in *PortInfo, opts ...grpc.CallOption) (*Ports, error)
+	// Get status of all or specific ONUs
+	ONUStatus(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*ONUs, error)
+	// Single/bulk activate ONU(s) for specific PON port(s)
+	ONUActivate(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*BBSimResponse, error)
+	// Deactivate ONU(s) for specific PON port(s) specified by
+	// a given onu_serial, onu_id, or pon_port_id
+	ONUDeactivate(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*BBSimResponse, error)
+	// Generate ONU related alarms
+	GenerateONUAlarm(ctx context.Context, in *ONUAlarmRequest, opts ...grpc.CallOption) (*BBSimResponse, error)
+	// Generate OLT related alarms
+	GenerateOLTAlarm(ctx context.Context, in *OLTAlarmRequest, opts ...grpc.CallOption) (*BBSimResponse, error)
+	// Perform actions on OLT/ONU devices (e.g. reboot)
+	PerformDeviceAction(ctx context.Context, in *DeviceAction, opts ...grpc.CallOption) (*BBSimResponse, error)
+	// Get flows
+	GetFlows(ctx context.Context, in *ONUInfo, opts ...grpc.CallOption) (*Flows, error)
+}
+
+type bBSimServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewBBSimServiceClient(cc *grpc.ClientConn) BBSimServiceClient {
+	return &bBSimServiceClient{cc}
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) OLTStatus(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*OLTStatusResponse, error) {
+	out := new(OLTStatusResponse)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/OLTStatus", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) PortStatus(ctx context.Context, in *PortInfo, opts ...grpc.CallOption) (*Ports, error) {
+	out := new(Ports)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/PortStatus", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) ONUStatus(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*ONUs, error) {
+	out := new(ONUs)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/ONUStatus", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) ONUActivate(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*BBSimResponse, error) {
+	out := new(BBSimResponse)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/ONUActivate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) ONUDeactivate(ctx context.Context, in *ONURequest, opts ...grpc.CallOption) (*BBSimResponse, error) {
+	out := new(BBSimResponse)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/ONUDeactivate", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) GenerateONUAlarm(ctx context.Context, in *ONUAlarmRequest, opts ...grpc.CallOption) (*BBSimResponse, error) {
+	out := new(BBSimResponse)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/GenerateONUAlarm", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) GenerateOLTAlarm(ctx context.Context, in *OLTAlarmRequest, opts ...grpc.CallOption) (*BBSimResponse, error) {
+	out := new(BBSimResponse)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/GenerateOLTAlarm", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) PerformDeviceAction(ctx context.Context, in *DeviceAction, opts ...grpc.CallOption) (*BBSimResponse, error) {
+	out := new(BBSimResponse)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/PerformDeviceAction", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Deprecated: Do not use.
+func (c *bBSimServiceClient) GetFlows(ctx context.Context, in *ONUInfo, opts ...grpc.CallOption) (*Flows, error) {
+	out := new(Flows)
+	err := c.cc.Invoke(ctx, "/legacy.BBSimService/GetFlows", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// BBSimServiceServer is the server API for BBSimService service.
+type BBSimServiceServer interface {
+	// Get current status of OLT
+	OLTStatus(context.Context, *Empty) (*OLTStatusResponse, error)
+	// Get status of a PON/NNI port
+	PortStatus(context.Context, *PortInfo) (*Ports, error)
+	// Get status of all or specific ONUs
+	ONUStatus(context.Context, *ONURequest) (*ONUs, error)
+	// Single/bulk activate ONU(s) for specific PON port(s)
+	ONUActivate(context.Context, *ONURequest) (*BBSimResponse, error)
+	// Deactivate ONU(s) for specific PON port(s) specified by
+	// a given onu_serial, onu_id, or pon_port_id
+	ONUDeactivate(context.Context, *ONURequest) (*BBSimResponse, error)
+	// Generate ONU related alarms
+	GenerateONUAlarm(context.Context, *ONUAlarmRequest) (*BBSimResponse, error)
+	// Generate OLT related alarms
+	GenerateOLTAlarm(context.Context, *OLTAlarmRequest) (*BBSimResponse, error)
+	// Perform actions on OLT/ONU devices (e.g. reboot)
+	PerformDeviceAction(context.Context, *DeviceAction) (*BBSimResponse, error)
+	// Get flows
+	GetFlows(context.Context, *ONUInfo) (*Flows, error)
+}
+
+// UnimplementedBBSimServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedBBSimServiceServer struct {
+}
+
+func (*UnimplementedBBSimServiceServer) OLTStatus(ctx context.Context, req *Empty) (*OLTStatusResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method OLTStatus not implemented")
+}
+func (*UnimplementedBBSimServiceServer) PortStatus(ctx context.Context, req *PortInfo) (*Ports, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PortStatus not implemented")
+}
+func (*UnimplementedBBSimServiceServer) ONUStatus(ctx context.Context, req *ONURequest) (*ONUs, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ONUStatus not implemented")
+}
+func (*UnimplementedBBSimServiceServer) ONUActivate(ctx context.Context, req *ONURequest) (*BBSimResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ONUActivate not implemented")
+}
+func (*UnimplementedBBSimServiceServer) ONUDeactivate(ctx context.Context, req *ONURequest) (*BBSimResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ONUDeactivate not implemented")
+}
+func (*UnimplementedBBSimServiceServer) GenerateONUAlarm(ctx context.Context, req *ONUAlarmRequest) (*BBSimResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GenerateONUAlarm not implemented")
+}
+func (*UnimplementedBBSimServiceServer) GenerateOLTAlarm(ctx context.Context, req *OLTAlarmRequest) (*BBSimResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GenerateOLTAlarm not implemented")
+}
+func (*UnimplementedBBSimServiceServer) PerformDeviceAction(ctx context.Context, req *DeviceAction) (*BBSimResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PerformDeviceAction not implemented")
+}
+func (*UnimplementedBBSimServiceServer) GetFlows(ctx context.Context, req *ONUInfo) (*Flows, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetFlows not implemented")
+}
+
+func RegisterBBSimServiceServer(s *grpc.Server, srv BBSimServiceServer) {
+	s.RegisterService(&_BBSimService_serviceDesc, srv)
+}
+
+func _BBSimService_OLTStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(Empty)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).OLTStatus(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/OLTStatus",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).OLTStatus(ctx, req.(*Empty))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_PortStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(PortInfo)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).PortStatus(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/PortStatus",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).PortStatus(ctx, req.(*PortInfo))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_ONUStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).ONUStatus(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/ONUStatus",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).ONUStatus(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_ONUActivate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).ONUActivate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/ONUActivate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).ONUActivate(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_ONUDeactivate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).ONUDeactivate(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/ONUDeactivate",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).ONUDeactivate(ctx, req.(*ONURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_GenerateONUAlarm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONUAlarmRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).GenerateONUAlarm(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/GenerateONUAlarm",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).GenerateONUAlarm(ctx, req.(*ONUAlarmRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_GenerateOLTAlarm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(OLTAlarmRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).GenerateOLTAlarm(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/GenerateOLTAlarm",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).GenerateOLTAlarm(ctx, req.(*OLTAlarmRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_PerformDeviceAction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(DeviceAction)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).PerformDeviceAction(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/PerformDeviceAction",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).PerformDeviceAction(ctx, req.(*DeviceAction))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _BBSimService_GetFlows_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ONUInfo)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(BBSimServiceServer).GetFlows(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/legacy.BBSimService/GetFlows",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(BBSimServiceServer).GetFlows(ctx, req.(*ONUInfo))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _BBSimService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "legacy.BBSimService",
+	HandlerType: (*BBSimServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "OLTStatus",
+			Handler:    _BBSimService_OLTStatus_Handler,
+		},
+		{
+			MethodName: "PortStatus",
+			Handler:    _BBSimService_PortStatus_Handler,
+		},
+		{
+			MethodName: "ONUStatus",
+			Handler:    _BBSimService_ONUStatus_Handler,
+		},
+		{
+			MethodName: "ONUActivate",
+			Handler:    _BBSimService_ONUActivate_Handler,
+		},
+		{
+			MethodName: "ONUDeactivate",
+			Handler:    _BBSimService_ONUDeactivate_Handler,
+		},
+		{
+			MethodName: "GenerateONUAlarm",
+			Handler:    _BBSimService_GenerateONUAlarm_Handler,
+		},
+		{
+			MethodName: "GenerateOLTAlarm",
+			Handler:    _BBSimService_GenerateOLTAlarm_Handler,
+		},
+		{
+			MethodName: "PerformDeviceAction",
+			Handler:    _BBSimService_PerformDeviceAction_Handler,
+		},
+		{
+			MethodName: "GetFlows",
+			Handler:    _BBSimService_GetFlows_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "api/legacy/bbsim.proto",
+}
diff --git a/api/legacy/bbsim.pb.gw.go b/api/legacy/bbsim.pb.gw.go
new file mode 100644
index 0000000..d56438c
--- /dev/null
+++ b/api/legacy/bbsim.pb.gw.go
@@ -0,0 +1,2328 @@
+// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
+// source: api/legacy/bbsim.proto
+
+/*
+Package legacy is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package legacy
+
+import (
+	"context"
+	"io"
+	"net/http"
+
+	"github.com/golang/protobuf/descriptor"
+	"github.com/golang/protobuf/proto"
+	"github.com/grpc-ecosystem/grpc-gateway/runtime"
+	"github.com/grpc-ecosystem/grpc-gateway/utilities"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/status"
+)
+
+// Suppress "imported and not used" errors
+var _ codes.Code
+var _ io.Reader
+var _ status.Status
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+var _ = descriptor.ForMessage
+
+func request_BBSimService_OLTStatus_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.OLTStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_OLTStatus_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.OLTStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSimService_OLTStatus_1(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.OLTStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_OLTStatus_1(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq Empty
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.OLTStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_PortStatus_0 = &utilities.DoubleArray{Encoding: map[string]int{"port_type": 0, "port_id": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
+)
+
+func request_BBSimService_PortStatus_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq PortInfo
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["port_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_type")
+	}
+
+	protoReq.PortType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_type", err)
+	}
+
+	val, ok = pathParams["port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id")
+	}
+
+	protoReq.PortId, err = runtime.Uint32(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_PortStatus_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.PortStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_PortStatus_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq PortInfo
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["port_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_type")
+	}
+
+	protoReq.PortType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_type", err)
+	}
+
+	val, ok = pathParams["port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id")
+	}
+
+	protoReq.PortId, err = runtime.Uint32(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_PortStatus_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.PortStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUStatus_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
+)
+
+func request_BBSimService_ONUStatus_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUStatus_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUStatus_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUStatus_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUStatus_1 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "onu_serial": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
+)
+
+func request_BBSimService_ONUStatus_1(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_serial")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_serial", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_serial", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUStatus_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUStatus_1(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_serial")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_serial", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_serial", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUStatus_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUStatus_2 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "pon_port_id": 1, "onu_id": 2}, Base: []int{1, 1, 1, 2, 0, 0}, Check: []int{0, 1, 2, 2, 3, 4}}
+)
+
+func request_BBSimService_ONUStatus_2(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	val, ok = pathParams["onu.onu_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUStatus_2); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUStatus_2(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	val, ok = pathParams["onu.onu_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_id", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUStatus_2); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUStatus_3 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "pon_port_id": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
+)
+
+func request_BBSimService_ONUStatus_3(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUStatus_3); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUStatus_3(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUStatus_3); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUStatus(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUActivate_0 = &utilities.DoubleArray{Encoding: map[string]int{"onus_batch": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
+)
+
+func request_BBSimService_ONUActivate_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.OnusBatch); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUActivate_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUActivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUActivate_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.OnusBatch); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUActivate_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUActivate(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUActivate_1 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "pon_port_id": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
+)
+
+func request_BBSimService_ONUActivate_1(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUActivate_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUActivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUActivate_1(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUActivate_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUActivate(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUActivate_2 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "pon_port_id": 1, "onu_serial": 2}, Base: []int{1, 1, 1, 2, 0, 0}, Check: []int{0, 1, 2, 2, 3, 4}}
+)
+
+func request_BBSimService_ONUActivate_2(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	val, ok = pathParams["onu.onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_serial")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_serial", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_serial", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUActivate_2); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUActivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUActivate_2(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	val, ok = pathParams["onu.onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_serial")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_serial", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_serial", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUActivate_2); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUActivate(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUDeactivate_0 = &utilities.DoubleArray{Encoding: map[string]int{"onus_batch": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
+)
+
+func request_BBSimService_ONUDeactivate_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.OnusBatch); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUDeactivate_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUDeactivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUDeactivate_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.OnusBatch); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUDeactivate_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUDeactivate(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUDeactivate_1 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "onu_serial": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
+)
+
+func request_BBSimService_ONUDeactivate_1(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_serial")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_serial", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_serial", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUDeactivate_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUDeactivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUDeactivate_1(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_serial")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_serial", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_serial", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUDeactivate_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUDeactivate(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUDeactivate_2 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "pon_port_id": 1}, Base: []int{1, 1, 1, 0}, Check: []int{0, 1, 2, 3}}
+)
+
+func request_BBSimService_ONUDeactivate_2(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUDeactivate_2); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUDeactivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUDeactivate_2(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUDeactivate_2); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUDeactivate(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_ONUDeactivate_3 = &utilities.DoubleArray{Encoding: map[string]int{"onu": 0, "pon_port_id": 1, "onu_id": 2}, Base: []int{1, 1, 1, 2, 0, 0}, Check: []int{0, 1, 2, 2, 3, 4}}
+)
+
+func request_BBSimService_ONUDeactivate_3(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	val, ok = pathParams["onu.onu_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_id", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_ONUDeactivate_3); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.ONUDeactivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_ONUDeactivate_3(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONURequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu.pon_port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.pon_port_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.pon_port_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.pon_port_id", err)
+	}
+
+	val, ok = pathParams["onu.onu_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu.onu_id")
+	}
+
+	err = runtime.PopulateFieldFromPath(&protoReq, "onu.onu_id", val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu.onu_id", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_ONUDeactivate_3); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.ONUDeactivate(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSimService_GenerateONUAlarm_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONUAlarmRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu_serial")
+	}
+
+	protoReq.OnuSerial, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu_serial", err)
+	}
+
+	val, ok = pathParams["alarm_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "alarm_type")
+	}
+
+	protoReq.AlarmType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "alarm_type", err)
+	}
+
+	val, ok = pathParams["status"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status")
+	}
+
+	protoReq.Status, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status", err)
+	}
+
+	msg, err := client.GenerateONUAlarm(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_GenerateONUAlarm_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONUAlarmRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu_serial")
+	}
+
+	protoReq.OnuSerial, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu_serial", err)
+	}
+
+	val, ok = pathParams["alarm_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "alarm_type")
+	}
+
+	protoReq.AlarmType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "alarm_type", err)
+	}
+
+	val, ok = pathParams["status"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status")
+	}
+
+	protoReq.Status, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status", err)
+	}
+
+	msg, err := server.GenerateONUAlarm(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSimService_GenerateOLTAlarm_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq OLTAlarmRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["port_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_type")
+	}
+
+	protoReq.PortType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_type", err)
+	}
+
+	val, ok = pathParams["port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id")
+	}
+
+	protoReq.PortId, err = runtime.Uint32(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err)
+	}
+
+	val, ok = pathParams["status"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status")
+	}
+
+	protoReq.Status, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status", err)
+	}
+
+	msg, err := client.GenerateOLTAlarm(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_GenerateOLTAlarm_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq OLTAlarmRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["port_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_type")
+	}
+
+	protoReq.PortType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_type", err)
+	}
+
+	val, ok = pathParams["port_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id")
+	}
+
+	protoReq.PortId, err = runtime.Uint32(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err)
+	}
+
+	val, ok = pathParams["status"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "status")
+	}
+
+	protoReq.Status, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "status", err)
+	}
+
+	msg, err := server.GenerateOLTAlarm(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_PerformDeviceAction_0 = &utilities.DoubleArray{Encoding: map[string]int{"device_type": 0, "action": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
+)
+
+func request_BBSimService_PerformDeviceAction_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq DeviceAction
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["device_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "device_type")
+	}
+
+	protoReq.DeviceType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "device_type", err)
+	}
+
+	val, ok = pathParams["action"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action")
+	}
+
+	protoReq.Action, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_PerformDeviceAction_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.PerformDeviceAction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_PerformDeviceAction_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq DeviceAction
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["device_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "device_type")
+	}
+
+	protoReq.DeviceType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "device_type", err)
+	}
+
+	val, ok = pathParams["action"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action")
+	}
+
+	protoReq.Action, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_PerformDeviceAction_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.PerformDeviceAction(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_BBSimService_PerformDeviceAction_1(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq DeviceAction
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["device_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "device_type")
+	}
+
+	protoReq.DeviceType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "device_type", err)
+	}
+
+	val, ok = pathParams["serial_number"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "serial_number")
+	}
+
+	protoReq.SerialNumber, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "serial_number", err)
+	}
+
+	val, ok = pathParams["action"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action")
+	}
+
+	protoReq.Action, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err)
+	}
+
+	msg, err := client.PerformDeviceAction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_PerformDeviceAction_1(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq DeviceAction
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["device_type"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "device_type")
+	}
+
+	protoReq.DeviceType, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "device_type", err)
+	}
+
+	val, ok = pathParams["serial_number"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "serial_number")
+	}
+
+	protoReq.SerialNumber, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "serial_number", err)
+	}
+
+	val, ok = pathParams["action"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action")
+	}
+
+	protoReq.Action, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err)
+	}
+
+	msg, err := server.PerformDeviceAction(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_GetFlows_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
+)
+
+func request_BBSimService_GetFlows_0(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONUInfo
+	var metadata runtime.ServerMetadata
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_GetFlows_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.GetFlows(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_GetFlows_0(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONUInfo
+	var metadata runtime.ServerMetadata
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_GetFlows_0); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.GetFlows(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+var (
+	filter_BBSimService_GetFlows_1 = &utilities.DoubleArray{Encoding: map[string]int{"onu_serial": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
+)
+
+func request_BBSimService_GetFlows_1(ctx context.Context, marshaler runtime.Marshaler, client BBSimServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONUInfo
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu_serial")
+	}
+
+	protoReq.OnuSerial, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu_serial", err)
+	}
+
+	if err := req.ParseForm(); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_BBSimService_GetFlows_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.GetFlows(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_BBSimService_GetFlows_1(ctx context.Context, marshaler runtime.Marshaler, server BBSimServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ONUInfo
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["onu_serial"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "onu_serial")
+	}
+
+	protoReq.OnuSerial, err = runtime.String(val)
+
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "onu_serial", err)
+	}
+
+	if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_BBSimService_GetFlows_1); err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.GetFlows(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+// RegisterBBSimServiceHandlerServer registers the http handlers for service BBSimService to "mux".
+// UnaryRPC     :call BBSimServiceServer directly.
+// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
+func RegisterBBSimServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server BBSimServiceServer) error {
+
+	mux.Handle("GET", pattern_BBSimService_OLTStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_OLTStatus_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_OLTStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_OLTStatus_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_OLTStatus_1(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_OLTStatus_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_PortStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_PortStatus_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_PortStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUStatus_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUStatus_1(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_2, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUStatus_2(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_3, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUStatus_3(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_ONUActivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUActivate_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUActivate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_ONUActivate_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUActivate_1(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUActivate_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_ONUActivate_2, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUActivate_2(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUActivate_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUDeactivate_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUDeactivate_1(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_2, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUDeactivate_2(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_3, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_ONUDeactivate_3(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_GenerateONUAlarm_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_GenerateONUAlarm_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GenerateONUAlarm_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_GenerateOLTAlarm_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_GenerateOLTAlarm_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GenerateOLTAlarm_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("PATCH", pattern_BBSimService_PerformDeviceAction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_PerformDeviceAction_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_PerformDeviceAction_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("PATCH", pattern_BBSimService_PerformDeviceAction_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_PerformDeviceAction_1(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_PerformDeviceAction_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_GetFlows_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_GetFlows_0(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GetFlows_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_GetFlows_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_BBSimService_GetFlows_1(rctx, inboundMarshaler, server, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GetFlows_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+// RegisterBBSimServiceHandlerFromEndpoint is same as RegisterBBSimServiceHandler but
+// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
+func RegisterBBSimServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
+	conn, err := grpc.Dial(endpoint, opts...)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if err != nil {
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+			return
+		}
+		go func() {
+			<-ctx.Done()
+			if cerr := conn.Close(); cerr != nil {
+				grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+			}
+		}()
+	}()
+
+	return RegisterBBSimServiceHandler(ctx, mux, conn)
+}
+
+// RegisterBBSimServiceHandler registers the http handlers for service BBSimService to "mux".
+// The handlers forward requests to the grpc endpoint over "conn".
+func RegisterBBSimServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+	return RegisterBBSimServiceHandlerClient(ctx, mux, NewBBSimServiceClient(conn))
+}
+
+// RegisterBBSimServiceHandlerClient registers the http handlers for service BBSimService
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "BBSimServiceClient".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "BBSimServiceClient"
+// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
+// "BBSimServiceClient" to call the correct interceptors.
+func RegisterBBSimServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client BBSimServiceClient) error {
+
+	mux.Handle("GET", pattern_BBSimService_OLTStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_OLTStatus_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_OLTStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_OLTStatus_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_OLTStatus_1(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_OLTStatus_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_PortStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_PortStatus_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_PortStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUStatus_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUStatus_1(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_2, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUStatus_2(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_ONUStatus_3, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUStatus_3(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUStatus_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_ONUActivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUActivate_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUActivate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_ONUActivate_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUActivate_1(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUActivate_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_ONUActivate_2, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUActivate_2(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUActivate_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUDeactivate_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUDeactivate_1(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_2, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUDeactivate_2(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_2(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_BBSimService_ONUDeactivate_3, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_ONUDeactivate_3(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_ONUDeactivate_3(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_GenerateONUAlarm_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_GenerateONUAlarm_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GenerateONUAlarm_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("POST", pattern_BBSimService_GenerateOLTAlarm_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_GenerateOLTAlarm_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GenerateOLTAlarm_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("PATCH", pattern_BBSimService_PerformDeviceAction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_PerformDeviceAction_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_PerformDeviceAction_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("PATCH", pattern_BBSimService_PerformDeviceAction_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_PerformDeviceAction_1(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_PerformDeviceAction_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_GetFlows_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_GetFlows_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GetFlows_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_BBSimService_GetFlows_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_BBSimService_GetFlows_1(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_BBSimService_GetFlows_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+var (
+	pattern_BBSimService_OLTStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v0", "olt"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_OLTStatus_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v0", "olt", "status"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_PortStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"v0", "olt", "ports", "port_type", "port_id", "status"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v0", "olt", "onus"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUStatus_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v0", "olt", "onus", "onu.onu_serial"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUStatus_2 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"v0", "olt", "ports", "onu.pon_port_id", "onus", "onu.onu_id"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUStatus_3 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"v0", "olt", "ports", "onu.pon_port_id", "onus"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUActivate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v0", "olt", "onus"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUActivate_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"v0", "olt", "ports", "onu.pon_port_id", "onus"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUActivate_2 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"v0", "olt", "ports", "onu.pon_port_id", "onus", "onu.onu_serial"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUDeactivate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v0", "olt", "onus"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUDeactivate_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v0", "olt", "onus", "onu.onu_serial"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUDeactivate_2 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"v0", "olt", "ports", "onu.pon_port_id", "onus"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_ONUDeactivate_3 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"v0", "olt", "ports", "onu.pon_port_id", "onus", "onu.onu_id"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_GenerateONUAlarm_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6}, []string{"v0", "olt", "onus", "onu_serial", "alarms", "alarm_type", "status"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_GenerateOLTAlarm_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 2, 5, 2, 6, 1, 0, 4, 1, 5, 7}, []string{"v0", "olt", "ports", "port_type", "port_id", "alarms", "los", "status"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_PerformDeviceAction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 2}, []string{"v0", "device_type", "action"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_PerformDeviceAction_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 4}, []string{"v0", "olt", "device_type", "serial_number", "action"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_GetFlows_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v0", "olt", "flows"}, "", runtime.AssumeColonVerbOpt(true)))
+
+	pattern_BBSimService_GetFlows_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"v0", "olt", "onu", "onu_serial", "flows"}, "", runtime.AssumeColonVerbOpt(true)))
+)
+
+var (
+	forward_BBSimService_OLTStatus_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_OLTStatus_1 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_PortStatus_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUStatus_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUStatus_1 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUStatus_2 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUStatus_3 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUActivate_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUActivate_1 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUActivate_2 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUDeactivate_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUDeactivate_1 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUDeactivate_2 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_ONUDeactivate_3 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_GenerateONUAlarm_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_GenerateOLTAlarm_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_PerformDeviceAction_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_PerformDeviceAction_1 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_GetFlows_0 = runtime.ForwardResponseMessage
+
+	forward_BBSimService_GetFlows_1 = runtime.ForwardResponseMessage
+)
