VOL-1103 Transfer BCM error code to GRPC error codes

Change-Id: I7636bfdfbec40fc244407d3cd57bbc6e7f5cefd8
diff --git a/src/core.cc b/src/core.cc
index 5bf3a62..e5f4949 100644
--- a/src/core.cc
+++ b/src/core.cc
@@ -26,6 +26,7 @@
 #include "core.h"
 #include "indications.h"
 #include "stats_collection.h"
+#include "error_format.h"
 
 extern "C"
 {
@@ -44,9 +45,10 @@
         key.access_term_id = DEFAULT_ATERM_ID;
         BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
         BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_UP);
-        if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr))) {
+        bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
+        if (err) {
             std::cout << "ERROR: Failed to enable OLT" << std::endl;
-            return Status(grpc::StatusCode::INTERNAL, "Failed to enable OLT");
+            return bcm_to_grpc_err(err, "Failed to enable OLT");
         }
         enabled = true;
     }
@@ -63,9 +65,10 @@
     BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
     BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_UP);
 
-    if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr))) {
+    bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
+    if (err) {
         std::cout << "ERROR: Failed to enable PON interface: " << intf_id << std::endl;
-        return Status(grpc::StatusCode::INTERNAL, "Failed to enable PON interface");
+        return bcm_to_grpc_err(err, "Failed to enable PON interface");
     }
 
     return Status::OK;
@@ -81,9 +84,10 @@
     BCMBAL_CFG_INIT(&interface_obj, interface, interface_key);
     BCMBAL_CFG_PROP_SET(&interface_obj, interface, admin_state, BCMBAL_STATE_DOWN);
 
-    if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr))) {
+    bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(interface_obj.hdr));
+    if (err) {
         std::cout << "ERROR: Failed to disable PON interface: " << intf_id << std::endl;
-        return Status(grpc::StatusCode::INTERNAL, "Failed to disable PON interface");
+        return bcm_to_grpc_err(err, "Failed to disable PON interface");
     }
 
     return Status::OK;
@@ -121,9 +125,10 @@
 
     BCMBAL_CFG_PROP_SET(&sub_term_obj, subscriber_terminal, admin_state, BCMBAL_STATE_UP);
 
-    if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr))) {
+    bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(sub_term_obj.hdr));
+    if (err) {
         std::cout << "ERROR: Failed to enable ONU: " << std::endl;
-        return Status(grpc::StatusCode::INTERNAL, "Failed to enable ONU");
+        return bcm_to_grpc_err(err, "Failed to enable ONU");
     }
 
     return SchedAdd_(intf_id, onu_id, mk_agg_port_id(onu_id));
@@ -259,7 +264,7 @@
         key.flow_type = BCMBAL_FLOW_TYPE_DOWNSTREAM;
     } else {
         std::cout << "Invalid flow type " << flow_type << std::endl;
-        return Status::CANCELLED;
+        return bcm_to_grpc_err(BCM_ERR_PARM, "Invalid flow type");
     }
 
     BCMBAL_CFG_INIT(&cfg, flow, key);
@@ -422,9 +427,10 @@
         BCMBAL_CFG_PROP_SET(&cfg, flow, dba_tm_sched_id, val);
     }
 
-    if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr))) {
+    err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
+    if (err) {
         std::cout << "ERROR: flow add failed" << std::endl;
-        return Status(grpc::StatusCode::INTERNAL, "flow add failed");
+        return bcm_to_grpc_err(err, "flow add failed");
     }
 
     register_new_flow(key);
@@ -456,12 +462,13 @@
         BCMBAL_CFG_PROP_SET(&cfg, tm_sched, owner, val);
     }
 
-    if (bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr))) {
+    bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(cfg.hdr));
+    if (err) {
         std::cout << "ERROR: Failed to create upstream DBA sched"
                   << " id:" << key.id
                   << " intf_id:" << intf_id
                   << " onu_id:" << onu_id << std::endl;
-        return Status(grpc::StatusCode::INTERNAL, "Failed to create upstream DBA sched");
+        return bcm_to_grpc_err(err, "Failed to create upstream DBA sched");
         //return 1;
     }
     std::cout << "create upstream DBA sched"
diff --git a/src/error_format.cc b/src/error_format.cc
new file mode 100644
index 0000000..5c88bc7
--- /dev/null
+++ b/src/error_format.cc
@@ -0,0 +1,41 @@
+#include "error_format.h"
+using grpc::Status;
+using grpc::StatusCode;
+
+
+Status bcm_to_grpc_err(bcmos_errno bcm_err, std::string message) {
+    StatusCode grpc_err = StatusCode::INTERNAL;
+
+    switch (bcm_err) {
+        case BCM_ERR_PARM:
+            grpc_err = StatusCode::INVALID_ARGUMENT;
+            break;
+        case BCM_ERR_RANGE:
+            grpc_err = StatusCode::OUT_OF_RANGE;
+            break;
+        case BCM_ERR_NOT_SUPPORTED:
+            grpc_err = StatusCode::UNIMPLEMENTED;
+            break;
+        case BCM_ERR_NOENT:
+        case BCM_ERR_NODEV:
+            grpc_err = StatusCode::NOT_FOUND;
+            break;
+        case BCM_ERR_TIMEOUT:
+        case BCM_ERR_TOO_LONG:
+        case BCM_ERR_TOO_MANY_REQS:
+            grpc_err = StatusCode::DEADLINE_EXCEEDED;
+            break;
+        case BCM_ERR_ALREADY:
+            grpc_err = StatusCode::ALREADY_EXISTS;
+            break;
+        case BCM_ERR_NO_MORE:
+        case BCM_ERR_INSUFFICIENT_LIST_MEM:
+            grpc_err = StatusCode::RESOURCE_EXHAUSTED;
+            break;
+    }
+
+    message.append(" BCM Error ");
+    message.append(std::to_string(bcm_err));
+
+    return Status(grpc_err, message);
+}
diff --git a/src/error_format.h b/src/error_format.h
new file mode 100644
index 0000000..5956fba
--- /dev/null
+++ b/src/error_format.h
@@ -0,0 +1,17 @@
+#ifndef OPENOLT_ERROR_FORMAT_H_
+#define OPENOLT_ERROR_FORMAT_H_
+
+#include <string>
+#include <grpc++/grpc++.h>
+
+extern "C"
+{
+#include <bcmos_system.h>
+#include <bal_api.h>
+#include <bal_api_end.h>
+}
+
+grpc::Status bcm_to_grpc_err(bcmos_errno bcm_err, std::string message);
+
+
+#endif