[VOL-1639][BAL3.0 Brigade] trap flows and packet-in
[VOL-1640][BAL3.0 Brigade] packet-out

Change-Id: Id797226d4da0e34adfb6f1dbedcd3e662aabc3a5
diff --git a/agent/common/core.h b/agent/common/core.h
index 47666ac..1fd3767 100644
--- a/agent/common/core.h
+++ b/agent/common/core.h
@@ -28,6 +28,13 @@
 
 extern State state;
 
+enum FLOW_CFG {
+    INTF_TYPE = 0,
+    INTF_ID = 1,
+	 SVC_PORT_ID = 2,
+	 COOKIE = 3
+};
+
 Status Enable_(int argc, char *argv[]);
 Status ActivateOnu_(uint32_t intf_id, uint32_t onu_id,
     const char *vendor_id, const char *vendor_specific, uint32_t pir);
@@ -64,6 +71,7 @@
 int get_status_bcm_cli_quit(void);
 uint16_t get_dev_id(void); 
 Status pushOltOperInd(uint32_t intf_id, const char *type, const char *state);
+uint64_t get_flow_status(uint16_t flow_id, uint16_t data_id);
 
 void stats_collection();
 #endif
diff --git a/agent/src/core.cc b/agent/src/core.cc
index 999601e..f6f9ab8 100644
--- a/agent/src/core.cc
+++ b/agent/src/core.cc
@@ -695,6 +695,56 @@
     return err;
 }
 
+uint64_t get_flow_status(uint16_t flow_id, uint16_t data_id) {
+    bcmos_errno err;
+    bcmolt_flow_key flow_key;
+    bcmolt_flow_cfg flow_cfg;
+
+    flow_key.flow_id = flow_id;
+
+    BCMOLT_CFG_INIT(&flow_cfg, flow, flow_key);
+
+    switch (data_id) {
+        case INTF_TYPE: //intf_type
+            BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
+            err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
+            if (err) {
+                BCM_LOG(ERROR, openolt_log_id,  "Failed to get intf_type\n");
+                return err;
+            }
+            return flow_cfg.data.ingress_intf.intf_type;
+        case INTF_ID: //intf_id
+            BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, ingress_intf);
+            err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
+            if (err) {
+                BCM_LOG(ERROR, openolt_log_id,  "Failed to get intf_id\n");
+                return err;
+            }
+            return flow_cfg.data.ingress_intf.intf_id;
+
+        case SVC_PORT_ID: //svc_port_id
+            BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
+            err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
+            if (err) {
+                BCM_LOG(ERROR, openolt_log_id,  "Failed to get svc_port_id\n");
+                return err;
+            }
+            return flow_cfg.data.svc_port_id;
+        case COOKIE: //cookie 
+            BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
+            err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
+            if (err) {
+                BCM_LOG(ERROR, openolt_log_id,  "Failed to get cookie\n");
+                return err;
+            }
+            return flow_cfg.data.cookie;
+        default:
+            return BCM_ERR_INTERNAL;
+    }
+
+	 return err;
+}
+
 Status EnablePonIf_(uint32_t intf_id) {
     bcmos_errno err = BCM_ERR_OK; 
     bcmolt_pon_interface_cfg interface_obj;
@@ -1231,7 +1281,7 @@
     uint32_t ether_type = 0;
 
     BCM_LOG(INFO, openolt_log_id, "flow add - intf_id %d, onu_id %d, uni_id %d, port_no %u, flow_id %d, flow_type %s, \
-            gemport_id %d, network_intf_id %d, cookie %"PRIu64"\n", \
+gemport_id %d, network_intf_id %d, cookie %"PRIu64"\n", \
             access_intf_id, onu_id, uni_id, port_no, flow_id, flow_type.c_str(), gemport_id, network_intf_id, cookie);
 
     key.flow_id = flow_id;
diff --git a/agent/src/indications.cc b/agent/src/indications.cc
index eb7570f..d938ea4 100644
--- a/agent/src/indications.cc
+++ b/agent/src/indications.cc
@@ -62,8 +62,12 @@
 #define SET_OPER_STATE(indication,state) \
        (INTERFACE_STATE_IF_UP(state)) ? indication->set_oper_state("up") : \
        indication->set_oper_state("down")
+#define GET_FLOW_TYPE(type) \
+       (type == BCMOLT_FLOW_TYPE_UPSTREAM) ? "upstream" : \
+       (type == BCMOLT_FLOW_TYPE_DOWNSTREAM) ? "downstream" : \
+       (type == BCMOLT_FLOW_TYPE_MULTICAST) ? "multicast" : "unknown"
 
-std::string bcmbal_to_grpc_intf_type(bcmolt_interface_type intf_type)
+std::string bcmolt_to_grpc_intf_type(bcmolt_interface_type intf_type)
 {
     if (intf_type == BCMOLT_INTERFACE_TYPE_NNI) {
         return "nni";
@@ -203,7 +207,7 @@
                     bcmolt_pon_interface_key *key = &((bcmolt_pon_interface_state_change_completed*)msg)->key;
                     bcmolt_pon_interface_state_change_completed_data *data = &((bcmolt_pon_interface_state_change_completed*)msg)->data;
                     intf_oper_ind->set_intf_id(key->pon_ni);
-                    intf_oper_ind->set_type(bcmbal_to_grpc_intf_type(BCMOLT_INTERFACE_TYPE_PON));
+                    intf_oper_ind->set_type(bcmolt_to_grpc_intf_type(BCMOLT_INTERFACE_TYPE_PON));
                     SET_OPER_STATE(intf_oper_ind, data->new_state);
                     BCM_LOG(INFO, openolt_log_id, "intf oper state indication, intf_type %s, intf_id %d, oper_state %s\n",
                         intf_oper_ind->type().c_str(), key->pon_ni, intf_oper_ind->oper_state().c_str());
@@ -220,7 +224,7 @@
                     bcmolt_interface intf_id = key->id;
                     bcmolt_interface_type intf_type = BCMOLT_INTERFACE_TYPE_NNI;
                     intf_oper_ind->set_intf_id(key->id);
-                    intf_oper_ind->set_type(bcmbal_to_grpc_intf_type(BCMOLT_INTERFACE_TYPE_NNI));
+                    intf_oper_ind->set_type(bcmolt_to_grpc_intf_type(BCMOLT_INTERFACE_TYPE_NNI));
                     SET_OPER_STATE(intf_oper_ind, data->new_state);           
                     BCM_LOG(INFO, openolt_log_id, "intf oper state indication, intf_type %s, intf_id %d, oper_state %s\n",
                         intf_oper_ind->type().c_str(), key->id, intf_oper_ind->oper_state().c_str());
@@ -432,27 +436,28 @@
     openolt::PacketIndication* pkt_ind = new openolt::PacketIndication;
 
     switch (msg->obj_type) {
-        case BCMOLT_OBJ_ID_ONU:
+        case BCMOLT_OBJ_ID_FLOW:
             switch (msg->subgroup) {
                 case BCMOLT_FLOW_AUTO_SUBGROUP_RECEIVE_ETH_PACKET:
                 {
-                    bcmolt_flow_key *key = &((bcmolt_flow_cfg*)msg)->key;
-                    bcmolt_flow_cfg_data *data = &((bcmolt_flow_cfg*)msg)->data;
+                    bcmolt_flow_receive_eth_packet *pkt = 
+                        (bcmolt_flow_receive_eth_packet*)msg;
                     bcmolt_flow_receive_eth_packet_data *pkt_data = 
                         &((bcmolt_flow_receive_eth_packet*)msg)->data;
 
-                    uint32_t port_no = GetPortNum_(key->flow_id);
-                    pkt_ind->set_intf_type(bcmbal_to_grpc_intf_type((bcmolt_interface_type)data->ingress_intf.intf_type));
-                    pkt_ind->set_intf_id(data->ingress_intf.intf_id);
-                    pkt_ind->set_gemport_id(data->svc_port_id);
-                    pkt_ind->set_flow_id(key->flow_id);
+                    uint32_t port_no = GetPortNum_(pkt->key.flow_id);
+                    pkt_ind->set_intf_type(bcmolt_to_grpc_intf_type((bcmolt_interface_type)get_flow_status(pkt->key.flow_id, INTF_TYPE)));
+                    pkt_ind->set_intf_id(get_flow_status(pkt->key.flow_id, INTF_ID));
+                    pkt_ind->set_gemport_id(get_flow_status(pkt->key.flow_id, SVC_PORT_ID));
+                    pkt_ind->set_flow_id(pkt->key.flow_id);
                     pkt_ind->set_pkt(pkt_data->buffer.arr, pkt_data->buffer.len);
                     pkt_ind->set_port_no(port_no);
-                    pkt_ind->set_cookie(data->cookie);
+                    pkt_ind->set_cookie(get_flow_status(pkt->key.flow_id, COOKIE));
                     ind.set_allocated_pkt_ind(pkt_ind);
 
-                    BCM_LOG(INFO, openolt_log_id, "packet indication, intf_type %s, intf_id %d, svc_port %d, flow_id %d port_no %d cookie %lu\n",
-                        pkt_ind->intf_type().c_str(), data->ingress_intf.intf_id, data->svc_port_id, key->flow_id, port_no, data->cookie);
+                    BCM_LOG(INFO, openolt_log_id, "packet indication, intf_type %s, intf_id %d, svc_port %d, flow_type %s, flow_id %d, port_no %d, cookie %"PRIu64"\n",
+                        pkt_ind->intf_type().c_str(), pkt_ind->intf_id(), pkt_ind->gemport_id(), GET_FLOW_TYPE(pkt->key.flow_type), 
+                        pkt_ind->flow_id(), port_no, pkt_ind->cookie());
                 }
             }
     }