VOL-929 Uplink packet out

Change-Id: I8d4e54b289de9b8413fa50126551e8ed94cb9e8b
diff --git a/protos/openolt.proto b/protos/openolt.proto
index a7915c8..069a7bc 100644
--- a/protos/openolt.proto
+++ b/protos/openolt.proto
@@ -39,6 +39,13 @@
         };
     }
 
+    rpc UplinkPacketOut(UplinkPacket) returns (Empty) {
+        option (google.api.http) = {
+          post: "/v1/UplinkPacketOut"
+          body: "*"
+        };
+    }
+
     rpc FlowAdd(Flow) returns (Empty) {
         option (google.api.http) = {
           post: "/v1/FlowAdd"
@@ -131,6 +138,11 @@
     bytes pkt = 3;
 }
 
+message UplinkPacket {
+    fixed32 intf_id = 1;
+    bytes pkt = 2;
+}
+
 message Classifier {
     fixed32 o_tpid = 1;
     fixed32 o_vid = 2;
diff --git a/src/core.cc b/src/core.cc
index 81444f1..c763072 100644
--- a/src/core.cc
+++ b/src/core.cc
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Open Networking Foundation 
+    Copyright (C) 2018 Open Networking Foundation
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -187,6 +187,28 @@
     return Status::OK;
 }
 
+Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt) {
+    bcmos_errno err = BCM_ERR_OK;
+    bcmbal_dest proxy_pkt_dest;
+    bcmbal_u8_list_u32_max_2048 buf;
+
+    proxy_pkt_dest.type = BCMBAL_DEST_TYPE_NNI,
+    proxy_pkt_dest.u.nni.intf_id = intf_id;
+
+    buf.len = pkt.size();
+    buf.val = (uint8_t *)malloc((buf.len)*sizeof(uint8_t));
+    memcpy(buf.val, (uint8_t *)pkt.data(), buf.len);
+
+    err = bcmbal_pkt_send(0, proxy_pkt_dest, (const char *)(buf.val), buf.len);
+
+    std::cout << "Packet out of length " << buf.len
+              << " sent through uplink port " << intf_id << std::endl;
+
+    free(buf.val);
+
+    return Status::OK;
+}
+
 Status FlowAdd_(uint32_t onu_id,
                 uint32_t flow_id, const std::string flow_type,
                 uint32_t access_intf_id, uint32_t network_intf_id,
diff --git a/src/core.h b/src/core.h
index f37bb29..ad92cf3 100644
--- a/src/core.h
+++ b/src/core.h
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Open Networking Foundation 
+    Copyright (C) 2018 Open Networking Foundation
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -28,6 +28,7 @@
 Status EnablePonIf_(uint32_t intf_id);
 Status OmciMsgOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt);
 Status OnuPacketOut_(uint32_t intf_id, uint32_t onu_id, const std::string pkt);
+Status UplinkPacketOut_(uint32_t intf_id, const std::string pkt);
 Status FlowAdd_(uint32_t onu_id,
                 uint32_t flow_id, const std::string flow_type,
                 uint32_t access_intf_id, uint32_t network_intf_id,
diff --git a/src/server.cc b/src/server.cc
index 263c3a1..9f926e8 100644
--- a/src/server.cc
+++ b/src/server.cc
@@ -73,6 +73,15 @@
             request->pkt());
     }
 
+    Status UplinkPacketOut(
+            ServerContext* context,
+            const openolt::UplinkPacket* request,
+            openolt::Empty* response) override {
+        return UplinkPacketOut_(
+            request->intf_id(),
+            request->pkt());
+    }
+
     Status FlowAdd(
             ServerContext* context,
             const openolt::Flow* request,